mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Compare commits
489 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e8edd2186 | ||
|
|
0ac1fc52dd | ||
|
|
6aa0143851 | ||
|
|
c7f6f8315f | ||
|
|
b0448fc6e0 | ||
|
|
3b8644da50 | ||
|
|
414c42bfcf | ||
|
|
952eda443b | ||
|
|
6a4a0b66bd | ||
|
|
079de53fa5 | ||
|
|
ce950ca2db | ||
|
|
49bd503308 | ||
|
|
5b20d9f326 | ||
|
|
5f8f69020b | ||
|
|
dc9325848a | ||
|
|
9df4c76bb8 | ||
|
|
0071c2e8a8 | ||
|
|
03727bdf55 | ||
|
|
5e39ba6642 | ||
|
|
d2ce4faa5a | ||
|
|
43b7aa2412 | ||
|
|
23b1682723 | ||
|
|
c53002f5fb | ||
|
|
ea37d9e73e | ||
|
|
ece7cec604 | ||
|
|
2e708d48ca | ||
|
|
109935bfce | ||
|
|
339d7188ed | ||
|
|
02f420012a | ||
|
|
d45ac54008 | ||
|
|
d9585478d9 | ||
|
|
01421e31a2 | ||
|
|
2f81b6363f | ||
|
|
53a7864c48 | ||
|
|
9fc3d9f3ca | ||
|
|
84911f9c05 | ||
|
|
77dc6dbb44 | ||
|
|
a36d19c4fc | ||
|
|
0fd6b4f71d | ||
|
|
52207cf6f9 | ||
|
|
0c26611d2d | ||
|
|
2a4fcb2c31 | ||
|
|
54930b6b55 | ||
|
|
4e5385c905 | ||
|
|
ac632f663e | ||
|
|
3620371c5c | ||
|
|
5dda502f84 | ||
|
|
590aec8fab | ||
|
|
75f8b06e50 | ||
|
|
e91e5d8c87 | ||
|
|
ef3cc72cb6 | ||
|
|
7a0a2a5001 | ||
|
|
bfdd4a9903 | ||
|
|
dc252fbf00 | ||
|
|
9f202c6f1e | ||
|
|
b933946d63 | ||
|
|
1b080fdcb9 | ||
|
|
a796be81a4 | ||
|
|
76f0650563 | ||
|
|
4707c3aa86 | ||
|
|
89a86ed422 | ||
|
|
f55a6d051b | ||
|
|
b343baceb4 | ||
|
|
abb5d04c3a | ||
|
|
94f66fc32e | ||
|
|
efd72cddcd | ||
|
|
def70b2e37 | ||
|
|
e5b35d64f7 | ||
|
|
02ef38020b | ||
|
|
16ed93cf61 | ||
|
|
86306a5cab | ||
|
|
1595ee4067 | ||
|
|
e22d0947c7 | ||
|
|
0dd9643ad5 | ||
|
|
14db78c53b | ||
|
|
84364ad11d | ||
|
|
160c0a3404 | ||
|
|
89449a0821 | ||
|
|
e1e35a2246 | ||
|
|
5f1082d0b1 | ||
|
|
1039348f12 | ||
|
|
a8d516b04e | ||
|
|
f1b1f13d3c | ||
|
|
a153dbae9b | ||
|
|
3d7e2a1f3d | ||
|
|
e1e9b3f9f6 | ||
|
|
3d18879fc4 | ||
|
|
cd12bf6317 | ||
|
|
1760432f6e | ||
|
|
a7d6a65d49 | ||
|
|
74d474e7df | ||
|
|
47e2f8a42c | ||
|
|
3cf273591a | ||
|
|
8ee2e10af4 | ||
|
|
165db26dc0 | ||
|
|
52d159c19f | ||
|
|
6abc9e5379 | ||
|
|
f722e43770 | ||
|
|
f483c7ea8a | ||
|
|
32cb4853c6 | ||
|
|
5c4b03c53e | ||
|
|
3a79cc3f5b | ||
|
|
71d0402e3e | ||
|
|
427f2f66d6 | ||
|
|
6ed74ac97c | ||
|
|
841d844f9c | ||
|
|
4387298e80 | ||
|
|
4f77286c3d | ||
|
|
4a242ac43d | ||
|
|
fe8cd812b0 | ||
|
|
b7249a2a42 | ||
|
|
7c42084503 | ||
|
|
8fb28db12d | ||
|
|
e777674a87 | ||
|
|
222ce4b49d | ||
|
|
4415d4e2d4 | ||
|
|
07c2081aac | ||
|
|
dd93c41618 | ||
|
|
441b3511de | ||
|
|
cf0bf73edc | ||
|
|
f719b23ef7 | ||
|
|
5110d803e4 | ||
|
|
6b59aa705a | ||
|
|
7b93328baf | ||
|
|
6adb70d3c4 | ||
|
|
c354f59fb6 | ||
|
|
637302a4c2 | ||
|
|
2aa9eb3ce8 | ||
|
|
f1c12d8ff0 | ||
|
|
6c4d57dc9e | ||
|
|
6870a39feb | ||
|
|
bb9981e24b | ||
|
|
74a0c08d70 | ||
|
|
18dc2107ea | ||
|
|
c28ba89fe2 | ||
|
|
c781bf2202 | ||
|
|
c30beb5974 | ||
|
|
7b160dcc82 | ||
|
|
c7266da750 | ||
|
|
eea99eb4e0 | ||
|
|
65a6d41510 | ||
|
|
210d510a90 | ||
|
|
549c32cb42 | ||
|
|
25a1160849 | ||
|
|
7670ff9272 | ||
|
|
21ae2afd4e | ||
|
|
171f513ecd | ||
|
|
c310bedb29 | ||
|
|
a661812ad7 | ||
|
|
f8d653d1f9 | ||
|
|
b942bb0043 | ||
|
|
f1ffadb6e0 | ||
|
|
204d1f1456 | ||
|
|
c285ed1033 | ||
|
|
818bf74b18 | ||
|
|
9d56215db8 | ||
|
|
c4ea9a916f | ||
|
|
24d56f2e0e | ||
|
|
b9a2a8d2aa | ||
|
|
5c97b48c29 | ||
|
|
a2d6c106a4 | ||
|
|
40ddac243e | ||
|
|
065c366b40 | ||
|
|
116dbf2c28 | ||
|
|
0ee9dede55 | ||
|
|
d107a371c6 | ||
|
|
a4afa90d16 | ||
|
|
e154c87504 | ||
|
|
fcc41f1b9a | ||
|
|
9a53659b08 | ||
|
|
9ccbaaf3dd | ||
|
|
1d5581ead2 | ||
|
|
3636a64667 | ||
|
|
148e579cc0 | ||
|
|
64ec5a1a6b | ||
|
|
2c932556fc | ||
|
|
bc000deaae | ||
|
|
92cd158c01 | ||
|
|
80473b48bb | ||
|
|
3b92f547f5 | ||
|
|
718e954df4 | ||
|
|
1eef23a1eb | ||
|
|
af3656d4ca | ||
|
|
7c6ed911b3 | ||
|
|
5be00b0e29 | ||
|
|
03326d9155 | ||
|
|
6111dce0e8 | ||
|
|
f98992725c | ||
|
|
c5198249a9 | ||
|
|
e6c8d0b72d | ||
|
|
caf7e6e7a7 | ||
|
|
ea7f12ebb5 | ||
|
|
a9508054c3 | ||
|
|
7f3fff3fec | ||
|
|
6ce4be6f84 | ||
|
|
ab95a8c1ef | ||
|
|
461620668c | ||
|
|
e4127b0f7d | ||
|
|
8180e13926 | ||
|
|
6eb4ce5f8e | ||
|
|
b89d81b2a8 | ||
|
|
73b1c0a660 | ||
|
|
4d05b107cf | ||
|
|
7621bbc2a5 | ||
|
|
c15d736be3 | ||
|
|
81bdde705c | ||
|
|
06fc5761fa | ||
|
|
a185bc485c | ||
|
|
96134409fc | ||
|
|
ab3fa2e123 | ||
|
|
ae6e5caa40 | ||
|
|
483beabab9 | ||
|
|
5c59564bfb | ||
|
|
1939c971a3 | ||
|
|
c2f9e6cb37 | ||
|
|
1641a6cdd5 | ||
|
|
fea50d40ea | ||
|
|
c1128efb6c | ||
|
|
20ca86888e | ||
|
|
36a1cd87d9 | ||
|
|
523e442a7b | ||
|
|
48048172e5 | ||
|
|
e9bd839b13 | ||
|
|
3df78d5afc | ||
|
|
352489edbe | ||
|
|
450c5e5d27 | ||
|
|
64cc5f8512 | ||
|
|
656712d48f | ||
|
|
971b32440c | ||
|
|
bb87f618bf | ||
|
|
2f9de52245 | ||
|
|
2136cfa17e | ||
|
|
39125654ce | ||
|
|
927d023cea | ||
|
|
1e2d2693b9 | ||
|
|
7634a44bfe | ||
|
|
2480d04ac7 | ||
|
|
c92536d926 | ||
|
|
80af7d6a47 | ||
|
|
87f9e301f9 | ||
|
|
542fb03968 | ||
|
|
f90d136c84 | ||
|
|
877a2b64c9 | ||
|
|
e6577f3c30 | ||
|
|
69e01a2999 | ||
|
|
5f71579a2d | ||
|
|
686e0749a5 | ||
|
|
385d8b5e42 | ||
|
|
4662c610c1 | ||
|
|
906a98fe39 | ||
|
|
1c4fdad7bd | ||
|
|
3f711f3356 | ||
|
|
b02ab76847 | ||
|
|
5fec52ced1 | ||
|
|
bde2bfcee8 | ||
|
|
eab7afe252 | ||
|
|
81e94eea02 | ||
|
|
a2a2c3c865 | ||
|
|
90cd199d4b | ||
|
|
b18e2d422b | ||
|
|
892c0a79ce | ||
|
|
59398aa2bb | ||
|
|
170914dbbc | ||
|
|
866d222d60 | ||
|
|
86a939451c | ||
|
|
9ff3150243 | ||
|
|
a7144f8d6a | ||
|
|
273738ba6f | ||
|
|
3fb42ff7b2 | ||
|
|
e90a14609a | ||
|
|
ece56baba0 | ||
|
|
1724dae8b8 | ||
|
|
190b46dd1f | ||
|
|
74daf12e52 | ||
|
|
c24844195d | ||
|
|
15752027ec | ||
|
|
bfc66e8b9a | ||
|
|
b60cbbef37 | ||
|
|
33b972d8b3 | ||
|
|
bb28a2aada | ||
|
|
acd0ce11aa | ||
|
|
01fb621733 | ||
|
|
71d1198ccd | ||
|
|
95ec3232c6 | ||
|
|
243249718b | ||
|
|
32a6db0f8c | ||
|
|
6fc0f2be70 | ||
|
|
70ac6c9230 | ||
|
|
609e425166 | ||
|
|
4ead16cdd6 | ||
|
|
361102f88b | ||
|
|
5d40715db6 | ||
|
|
e7c065ec71 | ||
|
|
18868228ad | ||
|
|
fbb0c510c5 | ||
|
|
a8d2459f8e | ||
|
|
9a266e5118 | ||
|
|
51e1aa1539 | ||
|
|
0137ed4f19 | ||
|
|
9d03711df8 | ||
|
|
1ca9072b51 | ||
|
|
9fd138e2b3 | ||
|
|
55fbf4fedd | ||
|
|
b87875abf8 | ||
|
|
ac2c97edff | ||
|
|
292dea7922 | ||
|
|
070b5958e0 | ||
|
|
3108fbf767 | ||
|
|
9df7f3d8e9 | ||
|
|
782fd81dee | ||
|
|
fa77d71335 | ||
|
|
3d1795da28 | ||
|
|
d1c2d6683c | ||
|
|
d8cf158e06 | ||
|
|
bc837b7975 | ||
|
|
68e8f2b833 | ||
|
|
3dc3a0ea2d | ||
|
|
79120a4c63 | ||
|
|
e0412f18fd | ||
|
|
40b0c43bda | ||
|
|
72f3e20e74 | ||
|
|
676a7a3271 | ||
|
|
f843239452 | ||
|
|
a4ab0c6b6a | ||
|
|
ef955ea8e5 | ||
|
|
8bd392ca0e | ||
|
|
8d2ac85797 | ||
|
|
6d6e5fcd43 | ||
|
|
9c9e90f6db | ||
|
|
7ffa27f347 | ||
|
|
c20043c8fd | ||
|
|
d18877f18d | ||
|
|
02c0cef97f | ||
|
|
c8e663fe87 | ||
|
|
7a875acfb0 | ||
|
|
3ec11d8f17 | ||
|
|
ec067ac5e3 | ||
|
|
316969d839 | ||
|
|
7a0a9581b5 | ||
|
|
8880be60fa | ||
|
|
e41713d52e | ||
|
|
b69e465d7a | ||
|
|
0db83fc571 | ||
|
|
1ac703f641 | ||
|
|
2c32368642 | ||
|
|
db40309e70 | ||
|
|
e36c1f7501 | ||
|
|
3aef5c1a2f | ||
|
|
ab6bb89980 | ||
|
|
983ace99d4 | ||
|
|
72fa6775e8 | ||
|
|
9f25cdf4f6 | ||
|
|
6e5edd68d3 | ||
|
|
e8978ffa99 | ||
|
|
c753fe7cc3 | ||
|
|
e59e345720 | ||
|
|
07c2244440 | ||
|
|
1865dccd58 | ||
|
|
f2e6ee9687 | ||
|
|
9219307e13 | ||
|
|
f2e8f96151 | ||
|
|
faf8af25ed | ||
|
|
106ba41c2a | ||
|
|
87939ea0dd | ||
|
|
e813640aa1 | ||
|
|
612b8f2749 | ||
|
|
ead8e1b796 | ||
|
|
3d4265f2d5 | ||
|
|
d66586ac90 | ||
|
|
44920624fb | ||
|
|
208058b9ad | ||
|
|
b4218b8473 | ||
|
|
3c2f0812f6 | ||
|
|
17bbd82f7d | ||
|
|
e1385337ff | ||
|
|
d367ecb475 | ||
|
|
c3b658b2c9 | ||
|
|
f9d655a8c8 | ||
|
|
ad3e4d1a49 | ||
|
|
222ed66f79 | ||
|
|
6bceebfabf | ||
|
|
2ca3eb8407 | ||
|
|
698205cddf | ||
|
|
2ecb33820f | ||
|
|
a0de6eb4ce | ||
|
|
7962ac1a58 | ||
|
|
9c97b053f3 | ||
|
|
f61b0d56f0 | ||
|
|
5087e016eb | ||
|
|
fa9f5d7170 | ||
|
|
6975534cb2 | ||
|
|
95c6d8db75 | ||
|
|
e0548e9ff3 | ||
|
|
c289ef20f3 | ||
|
|
b8cf157e8c | ||
|
|
b4d2b404b0 | ||
|
|
70fcaf9bd8 | ||
|
|
2f31c6b1d8 | ||
|
|
9e55467b4c | ||
|
|
35bf99c63e | ||
|
|
f9b8729597 | ||
|
|
4b2e7f26aa | ||
|
|
5202bc92e6 | ||
|
|
9d83411cc4 | ||
|
|
556c03a09d | ||
|
|
ce463b9fa4 | ||
|
|
477d1e8192 | ||
|
|
0eaff8fdf2 | ||
|
|
582c96691b | ||
|
|
0b22158d9f | ||
|
|
dafdb0d8a8 | ||
|
|
1d1686c62b | ||
|
|
ad95b924d0 | ||
|
|
9499684320 | ||
|
|
5b6a31626b | ||
|
|
bc3fee2d8e | ||
|
|
eaa9223277 | ||
|
|
c9ba1165e7 | ||
|
|
dd2d5d67ff | ||
|
|
404322b64f | ||
|
|
ce37bae2cd | ||
|
|
3900dbc341 | ||
|
|
5f586c2bd0 | ||
|
|
215f88a417 | ||
|
|
2257f40f4a | ||
|
|
9e0fa0ef6d | ||
|
|
0fddbf3dc7 | ||
|
|
eda635bd58 | ||
|
|
26197bb467 | ||
|
|
772e59d475 | ||
|
|
e8f83cbb5d | ||
|
|
dce584d799 | ||
|
|
0bcef9557d | ||
|
|
2b3c876b2a | ||
|
|
a05f6aad0e | ||
|
|
59187285e1 | ||
|
|
1dd074ea7e | ||
|
|
24fa7a01bd | ||
|
|
e236d3443c | ||
|
|
4ec8833220 | ||
|
|
dd3685cc6a | ||
|
|
487a6e6515 | ||
|
|
75f0b8aae3 | ||
|
|
23aca8a586 | ||
|
|
28bf2bf070 | ||
|
|
0164f4c682 | ||
|
|
bbff608a42 | ||
|
|
ea56d2ff2c | ||
|
|
a4c8701e9a | ||
|
|
a9bb9796e0 | ||
|
|
449883be74 | ||
|
|
0a08d4c60b | ||
|
|
4086187e49 | ||
|
|
91864f85d3 | ||
|
|
c3597106ab | ||
|
|
aed1d6597f | ||
|
|
b6f04a2dd4 | ||
|
|
a9aa3bcf50 | ||
|
|
32b8da66e3 | ||
|
|
eb94179ea3 | ||
|
|
52a7386aef | ||
|
|
8cada1d894 | ||
|
|
6e4a664c42 | ||
|
|
1cd1a96d56 | ||
|
|
86ab00cdcf | ||
|
|
65f09be8d2 | ||
|
|
400d756b82 | ||
|
|
9d31798a84 | ||
|
|
723ed92e0e | ||
|
|
0a7de0b273 | ||
|
|
d6b9bc1ccd | ||
|
|
0eff51e2ed | ||
|
|
1b7dd46d94 | ||
|
|
b2eb1bf3dc | ||
|
|
fe48c25682 | ||
|
|
0ba6da3470 | ||
|
|
a287140f72 | ||
|
|
4d89ec8a00 | ||
|
|
441760f239 | ||
|
|
664162fb8a | ||
|
|
aa3c761002 | ||
|
|
94f2cfc9c7 | ||
|
|
4a13d79df6 | ||
|
|
463176cc44 | ||
|
|
5aab97fba6 | ||
|
|
89abc6806d | ||
|
|
baf793ebaa | ||
|
|
b4ddafcfac | ||
|
|
1079967710 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -35,7 +35,3 @@ lapack/reference
|
|||||||
.*project
|
.*project
|
||||||
.settings
|
.settings
|
||||||
Makefile
|
Makefile
|
||||||
!ci/build.gitlab-ci.yml
|
|
||||||
!scripts/buildtests.in
|
|
||||||
!Eigen/Core
|
|
||||||
!Eigen/src/Core
|
|
||||||
|
|||||||
@@ -1,69 +0,0 @@
|
|||||||
<!--
|
|
||||||
Please read this!
|
|
||||||
|
|
||||||
Before opening a new issue, make sure to search for keywords in the issues
|
|
||||||
filtered by "bug::confirmed" or "bug::unconfirmed" and "bugzilla" label:
|
|
||||||
|
|
||||||
- https://gitlab.com/libeigen/eigen/-/issues?scope=all&utf8=%E2%9C%93&state=opened&label_name[]=bug%3A%3Aconfirmed
|
|
||||||
- https://gitlab.com/libeigen/eigen/-/issues?scope=all&utf8=%E2%9C%93&state=opened&label_name[]=bug%3A%3Aunconfirmed
|
|
||||||
- https://gitlab.com/libeigen/eigen/-/issues?scope=all&utf8=%E2%9C%93&state=opened&label_name[]=bugzilla
|
|
||||||
|
|
||||||
and verify the issue you're about to submit isn't a duplicate. -->
|
|
||||||
|
|
||||||
### Summary
|
|
||||||
<!-- Summarize the bug encountered concisely. -->
|
|
||||||
|
|
||||||
### Environment
|
|
||||||
<!-- Please provide your development environment here -->
|
|
||||||
- **Operating System** : Windows/Linux
|
|
||||||
- **Architecture** : x64/Arm64/PowerPC ...
|
|
||||||
- **Eigen Version** : 3.3.9
|
|
||||||
- **Compiler Version** : Gcc7.0
|
|
||||||
- **Compile Flags** : -O3 -march=native
|
|
||||||
- **Vector Extension** : SSE/AVX/NEON ...
|
|
||||||
|
|
||||||
### Minimal Example
|
|
||||||
<!-- If possible, please create a minimal example here that exhibits the problematic behavior.
|
|
||||||
You can also link to [godbolt](https://godbolt.org). But please note that you need to click
|
|
||||||
the "Share" button in the top right-hand corner of the godbolt page where you reproduce the sample
|
|
||||||
code to get the share link instead of in your browser address bar.
|
|
||||||
|
|
||||||
You can read [the guidelines on stackoverflow](https://stackoverflow.com/help/minimal-reproducible-example)
|
|
||||||
on how to create a good minimal example. -->
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
//show your code here
|
|
||||||
```
|
|
||||||
|
|
||||||
### Steps to reproduce
|
|
||||||
<!-- Describe how one can reproduce the issue - this is very important. Please use an ordered list. -->
|
|
||||||
|
|
||||||
1. first step
|
|
||||||
2. second step
|
|
||||||
3. ...
|
|
||||||
|
|
||||||
### What is the current *bug* behavior?
|
|
||||||
<!-- Describe what actually happens. -->
|
|
||||||
|
|
||||||
### What is the expected *correct* behavior?
|
|
||||||
<!-- Describe what you should see instead. -->
|
|
||||||
|
|
||||||
### Relevant logs
|
|
||||||
<!-- Add relevant code snippets or program output within blocks marked by " ``` " -->
|
|
||||||
|
|
||||||
<!-- OPTIONAL: remove this section if you are not reporting a compilation warning issue.-->
|
|
||||||
### Warning Messages
|
|
||||||
<!-- Show us the warning messages you got! -->
|
|
||||||
|
|
||||||
<!-- OPTIONAL: remove this section if you are not reporting a performance issue. -->
|
|
||||||
### Benchmark scripts and results
|
|
||||||
<!-- Please share any benchmark scripts - either standalone, or using [Google Benchmark](https://github.com/google/benchmark). -->
|
|
||||||
|
|
||||||
### Anything else that might help
|
|
||||||
<!-- It will be better to provide us more information to help narrow down the cause.
|
|
||||||
Including but not limited to the following:
|
|
||||||
- lines of code that might help us diagnose the problem.
|
|
||||||
- potential ways to address the issue.
|
|
||||||
- last known working/first broken version (release number or commit hash). -->
|
|
||||||
|
|
||||||
- [ ] Have a plan to fix this issue.
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
### Describe the feature you would like to be implemented.
|
|
||||||
|
|
||||||
### Would such a feature be useful for other users? Why?
|
|
||||||
|
|
||||||
### Any hints on how to implement the requested feature?
|
|
||||||
|
|
||||||
### Additional resources
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
<!--
|
|
||||||
Thanks for contributing a merge request! Please name and fully describe your MR as you would for a commit message.
|
|
||||||
If the MR fixes an issue, please include "Fixes #issue" in the commit message and the MR description.
|
|
||||||
|
|
||||||
In addition, we recommend that first-time contributors read our [contribution guidelines](https://eigen.tuxfamily.org/index.php?title=Contributing_to_Eigen) and [git page](https://eigen.tuxfamily.org/index.php?title=Git), which will help you submit a more standardized MR.
|
|
||||||
|
|
||||||
Before submitting the MR, you also need to complete the following checks:
|
|
||||||
- Make one PR per feature/bugfix (don't mix multiple changes into one PR). Avoid committing unrelated changes.
|
|
||||||
- Rebase before committing
|
|
||||||
- For code changes, run the test suite (at least the tests that are likely affected by the change).
|
|
||||||
See our [test guidelines](https://eigen.tuxfamily.org/index.php?title=Tests).
|
|
||||||
- If possible, add a test (both for bug-fixes as well as new features)
|
|
||||||
- Make sure new features are documented
|
|
||||||
|
|
||||||
Note that we are a team of volunteers; we appreciate your patience during the review process.
|
|
||||||
|
|
||||||
Again, thanks for contributing! -->
|
|
||||||
|
|
||||||
### Reference issue
|
|
||||||
<!-- You can link to a specific issue using the gitlab syntax #<issue number> -->
|
|
||||||
|
|
||||||
### What does this implement/fix?
|
|
||||||
<!--Please explain your changes.-->
|
|
||||||
|
|
||||||
### Additional information
|
|
||||||
<!--Any additional information you think is important.-->
|
|
||||||
1233
CMakeLists.txt
1233
CMakeLists.txt
File diff suppressed because it is too large
Load Diff
203
COPYING.APACHE
203
COPYING.APACHE
@@ -1,203 +0,0 @@
|
|||||||
/*
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
@@ -49,3 +49,4 @@ SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT
|
|||||||
(INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE,
|
(INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE,
|
||||||
EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE
|
EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE
|
||||||
POSSIBILITY OF SUCH LOSS OR DAMAGES.
|
POSSIBILITY OF SUCH LOSS OR DAMAGES.
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
## Then modify the CMakeLists.txt file in the root directory of your
|
## Then modify the CMakeLists.txt file in the root directory of your
|
||||||
## project to incorporate the testing dashboard.
|
## project to incorporate the testing dashboard.
|
||||||
## # The following are required to uses Dart and the Cdash dashboard
|
## # The following are required to uses Dart and the Cdash dashboard
|
||||||
## enable_testing()
|
## ENABLE_TESTING()
|
||||||
## include(CTest)
|
## INCLUDE(CTest)
|
||||||
set(CTEST_PROJECT_NAME "Eigen")
|
set(CTEST_PROJECT_NAME "Eigen")
|
||||||
set(CTEST_NIGHTLY_START_TIME "00:00:00 UTC")
|
set(CTEST_NIGHTLY_START_TIME "00:00:00 UTC")
|
||||||
|
|
||||||
@@ -11,7 +11,3 @@ set(CTEST_DROP_METHOD "http")
|
|||||||
set(CTEST_DROP_SITE "my.cdash.org")
|
set(CTEST_DROP_SITE "my.cdash.org")
|
||||||
set(CTEST_DROP_LOCATION "/submit.php?project=Eigen")
|
set(CTEST_DROP_LOCATION "/submit.php?project=Eigen")
|
||||||
set(CTEST_DROP_SITE_CDASH TRUE)
|
set(CTEST_DROP_SITE_CDASH TRUE)
|
||||||
#set(CTEST_PROJECT_SUBPROJECTS
|
|
||||||
#Official
|
|
||||||
#Unsupported
|
|
||||||
#)
|
|
||||||
|
|||||||
19
Eigen/CMakeLists.txt
Normal file
19
Eigen/CMakeLists.txt
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
include(RegexUtils)
|
||||||
|
test_escape_string_as_regex()
|
||||||
|
|
||||||
|
file(GLOB Eigen_directory_files "*")
|
||||||
|
|
||||||
|
escape_string_as_regex(ESCAPED_CMAKE_CURRENT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
|
|
||||||
|
foreach(f ${Eigen_directory_files})
|
||||||
|
if(NOT f MATCHES "\\.txt" AND NOT f MATCHES "${ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/[.].+" AND NOT f MATCHES "${ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||||
|
list(APPEND Eigen_directory_files_to_install ${f})
|
||||||
|
endif()
|
||||||
|
endforeach(f ${Eigen_directory_files})
|
||||||
|
|
||||||
|
install(FILES
|
||||||
|
${Eigen_directory_files_to_install}
|
||||||
|
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen COMPONENT Devel
|
||||||
|
)
|
||||||
|
|
||||||
|
install(DIRECTORY src DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen COMPONENT Devel FILES_MATCHING PATTERN "*.h")
|
||||||
@@ -43,3 +43,4 @@
|
|||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_CHOLESKY_MODULE_H
|
#endif // EIGEN_CHOLESKY_MODULE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ extern "C" {
|
|||||||
* This module provides an interface to the Cholmod library which is part of the <a href="http://www.suitesparse.com">suitesparse</a> package.
|
* This module provides an interface to the Cholmod library which is part of the <a href="http://www.suitesparse.com">suitesparse</a> package.
|
||||||
* It provides the two following main factorization classes:
|
* It provides the two following main factorization classes:
|
||||||
* - class CholmodSupernodalLLT: a supernodal LLT Cholesky factorization.
|
* - class CholmodSupernodalLLT: a supernodal LLT Cholesky factorization.
|
||||||
* - class CholmodDecomposition: a general L(D)LT Cholesky factorization with automatic or explicit runtime selection of the underlying factorization method (supernodal or simplicial).
|
* - class CholmodDecomposiiton: a general L(D)LT Cholesky factorization with automatic or explicit runtime selection of the underlying factorization method (supernodal or simplicial).
|
||||||
*
|
*
|
||||||
* For the sake of completeness, this module also propose the two following classes:
|
* For the sake of completeness, this module also propose the two following classes:
|
||||||
* - class CholmodSimplicialLLT
|
* - class CholmodSimplicialLLT
|
||||||
|
|||||||
400
Eigen/Core
400
Eigen/Core
@@ -11,55 +11,264 @@
|
|||||||
#ifndef EIGEN_CORE_H
|
#ifndef EIGEN_CORE_H
|
||||||
#define EIGEN_CORE_H
|
#define EIGEN_CORE_H
|
||||||
|
|
||||||
// first thing Eigen does: stop the compiler from reporting useless warnings.
|
// first thing Eigen does: stop the compiler from committing suicide
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
// then include this file where all our macros are defined. It's really important to do it first because
|
#if defined(__CUDACC__) && !defined(EIGEN_NO_CUDA)
|
||||||
// it's where we do all the compiler/OS/arch detections and define most defaults.
|
#define EIGEN_CUDACC __CUDACC__
|
||||||
#include "src/Core/util/Macros.h"
|
|
||||||
|
|
||||||
// This detects SSE/AVX/NEON/etc. and configure alignment settings
|
|
||||||
#include "src/Core/util/ConfigureVectorization.h"
|
|
||||||
|
|
||||||
// We need cuda_runtime.h/hip_runtime.h to ensure that
|
|
||||||
// the EIGEN_USING_STD macro works properly on the device side
|
|
||||||
#if defined(EIGEN_CUDACC)
|
|
||||||
#include <cuda_runtime.h>
|
|
||||||
#elif defined(EIGEN_HIPCC)
|
|
||||||
#include <hip/hip_runtime.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__CUDA_ARCH__) && !defined(EIGEN_NO_CUDA)
|
||||||
|
#define EIGEN_CUDA_ARCH __CUDA_ARCH__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__CUDACC_VER_MAJOR__) && (__CUDACC_VER_MAJOR__ >= 9)
|
||||||
|
#define EIGEN_CUDACC_VER ((__CUDACC_VER_MAJOR__ * 10000) + (__CUDACC_VER_MINOR__ * 100))
|
||||||
|
#elif defined(__CUDACC_VER__)
|
||||||
|
#define EIGEN_CUDACC_VER __CUDACC_VER__
|
||||||
|
#else
|
||||||
|
#define EIGEN_CUDACC_VER 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Handle NVCC/CUDA/SYCL
|
||||||
|
#if defined(EIGEN_CUDACC) || defined(__SYCL_DEVICE_ONLY__)
|
||||||
|
// Do not try asserts on CUDA and SYCL!
|
||||||
|
#ifndef EIGEN_NO_DEBUG
|
||||||
|
#define EIGEN_NO_DEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef EIGEN_INTERNAL_DEBUGGING
|
||||||
|
#undef EIGEN_INTERNAL_DEBUGGING
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
|
#undef EIGEN_EXCEPTIONS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// All functions callable from CUDA code must be qualified with __device__
|
||||||
|
#ifdef EIGEN_CUDACC
|
||||||
|
// Do not try to vectorize on CUDA and SYCL!
|
||||||
|
#ifndef EIGEN_DONT_VECTORIZE
|
||||||
|
#define EIGEN_DONT_VECTORIZE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define EIGEN_DEVICE_FUNC __host__ __device__
|
||||||
|
// We need cuda_runtime.h to ensure that that EIGEN_USING_STD_MATH macro
|
||||||
|
// works properly on the device side
|
||||||
|
#include <cuda_runtime.h>
|
||||||
|
#else
|
||||||
|
#define EIGEN_DEVICE_FUNC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define EIGEN_DEVICE_FUNC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(EIGEN_CUDACC)
|
||||||
|
#include <cuda.h>
|
||||||
|
#define EIGEN_CUDA_SDK_VER (CUDA_VERSION * 10)
|
||||||
|
#else
|
||||||
|
#define EIGEN_CUDA_SDK_VER 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// When compiling CUDA device code with NVCC, pull in math functions from the
|
||||||
|
// global namespace. In host mode, and when device doee with clang, use the
|
||||||
|
// std versions.
|
||||||
|
#if defined(__CUDA_ARCH__) && defined(__NVCC__)
|
||||||
|
#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) && !defined(EIGEN_USE_SYCL)
|
||||||
|
#define EIGEN_EXCEPTIONS
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef EIGEN_EXCEPTIONS
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
#include <new>
|
#include <new>
|
||||||
#endif
|
#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.
|
||||||
|
#include "src/Core/util/Macros.h"
|
||||||
|
|
||||||
// Disable the ipa-cp-clone optimization flag with MinGW 6.x or newer (enabled by default with -O3)
|
// 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.
|
// See http://eigen.tuxfamily.org/bz/show_bug.cgi?id=556 for details.
|
||||||
#if EIGEN_COMP_MINGW && EIGEN_GNUC_AT_LEAST(4,6) && EIGEN_GNUC_AT_MOST(5,5)
|
#if EIGEN_COMP_MINGW && EIGEN_GNUC_AT_LEAST(4,6)
|
||||||
#pragma GCC optimize ("-fno-ipa-cp-clone")
|
#pragma GCC optimize ("-fno-ipa-cp-clone")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Prevent ICC from specializing std::complex operators that silently fail
|
|
||||||
// on device. This allows us to use our own device-compatible specializations
|
|
||||||
// instead.
|
|
||||||
#if defined(EIGEN_COMP_ICC) && defined(EIGEN_GPU_COMPILE_PHASE) \
|
|
||||||
&& !defined(_OVERRIDE_COMPLEX_SPECIALIZATION_)
|
|
||||||
#define _OVERRIDE_COMPLEX_SPECIALIZATION_ 1
|
|
||||||
#endif
|
|
||||||
#include <complex>
|
#include <complex>
|
||||||
|
|
||||||
// this include file manages BLAS and MKL related macros
|
// this include file manages BLAS and MKL related macros
|
||||||
// and inclusion of their respective header files
|
// and inclusion of their respective header files
|
||||||
#include "src/Core/util/MKL_support.h"
|
#include "src/Core/util/MKL_support.h"
|
||||||
|
|
||||||
|
// if alignment is disabled, then disable vectorization. Note: EIGEN_MAX_ALIGN_BYTES is the proper check, it takes into
|
||||||
#if defined(EIGEN_HAS_CUDA_FP16) || defined(EIGEN_HAS_HIP_FP16)
|
// account both the user's will (EIGEN_MAX_ALIGN_BYTES,EIGEN_DONT_ALIGN) and our own platform checks
|
||||||
#define EIGEN_HAS_GPU_FP16
|
#if EIGEN_MAX_ALIGN_BYTES==0
|
||||||
|
#ifndef EIGEN_DONT_VECTORIZE
|
||||||
|
#define EIGEN_DONT_VECTORIZE
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(EIGEN_HAS_CUDA_BF16) || defined(EIGEN_HAS_HIP_BF16)
|
#if EIGEN_COMP_MSVC
|
||||||
#define EIGEN_HAS_GPU_BF16
|
#include <malloc.h> // for _aligned_malloc -- need it regardless of whether vectorization is enabled
|
||||||
|
#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)) || 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__) && ( (!EIGEN_COMP_GNUC) || EIGEN_COMP_ICC || EIGEN_GNUC_AT_LEAST(4,2) )
|
||||||
|
#define EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(EIGEN_DONT_VECTORIZE) && !defined(EIGEN_CUDACC)
|
||||||
|
|
||||||
|
#if defined (EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER)
|
||||||
|
|
||||||
|
// Defines symbols for compile-time detection of which instructions are
|
||||||
|
// used.
|
||||||
|
// EIGEN_VECTORIZE_YY is defined if and only if the instruction set YY is used
|
||||||
|
#define EIGEN_VECTORIZE
|
||||||
|
#define EIGEN_VECTORIZE_SSE
|
||||||
|
#define EIGEN_VECTORIZE_SSE2
|
||||||
|
|
||||||
|
// Detect sse3/ssse3/sse4:
|
||||||
|
// gcc and icc defines __SSE3__, ...
|
||||||
|
// there is no way to know about this on msvc. You can define EIGEN_VECTORIZE_SSE* if you
|
||||||
|
// want to force the use of those instructions with msvc.
|
||||||
|
#ifdef __SSE3__
|
||||||
|
#define EIGEN_VECTORIZE_SSE3
|
||||||
|
#endif
|
||||||
|
#ifdef __SSSE3__
|
||||||
|
#define EIGEN_VECTORIZE_SSSE3
|
||||||
|
#endif
|
||||||
|
#ifdef __SSE4_1__
|
||||||
|
#define EIGEN_VECTORIZE_SSE4_1
|
||||||
|
#endif
|
||||||
|
#ifdef __SSE4_2__
|
||||||
|
#define EIGEN_VECTORIZE_SSE4_2
|
||||||
|
#endif
|
||||||
|
#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
|
||||||
|
#if defined(__AVX512F__) && defined(EIGEN_ENABLE_AVX512)
|
||||||
|
#define EIGEN_VECTORIZE_AVX512
|
||||||
|
#define EIGEN_VECTORIZE_AVX2
|
||||||
|
#define EIGEN_VECTORIZE_AVX
|
||||||
|
#define EIGEN_VECTORIZE_FMA
|
||||||
|
#ifdef __AVX512DQ__
|
||||||
|
#define EIGEN_VECTORIZE_AVX512DQ
|
||||||
|
#endif
|
||||||
|
#ifdef __AVX512ER__
|
||||||
|
#define EIGEN_VECTORIZE_AVX512ER
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// include files
|
||||||
|
|
||||||
|
// This extern "C" works around a MINGW-w64 compilation issue
|
||||||
|
// https://sourceforge.net/tracker/index.php?func=detail&aid=3018394&group_id=202880&atid=983354
|
||||||
|
// In essence, intrin.h is included by windows.h and also declares intrinsics (just as emmintrin.h etc. below do).
|
||||||
|
// However, intrin.h uses an extern "C" declaration, and g++ thus complains of duplicate declarations
|
||||||
|
// with conflicting linkage. The linkage for intrinsics doesn't matter, but at that stage the compiler doesn't know;
|
||||||
|
// so, to avoid compile errors when windows.h is included after Eigen/Core, ensure intrinsics are extern "C" here too.
|
||||||
|
// notice that since these are C headers, the extern "C" is theoretically needed anyways.
|
||||||
|
extern "C" {
|
||||||
|
// 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:
|
||||||
|
#if EIGEN_COMP_ICC >= 1110
|
||||||
|
#include <immintrin.h>
|
||||||
|
#else
|
||||||
|
#include <mmintrin.h>
|
||||||
|
#include <emmintrin.h>
|
||||||
|
#include <xmmintrin.h>
|
||||||
|
#ifdef EIGEN_VECTORIZE_SSE3
|
||||||
|
#include <pmmintrin.h>
|
||||||
|
#endif
|
||||||
|
#ifdef EIGEN_VECTORIZE_SSSE3
|
||||||
|
#include <tmmintrin.h>
|
||||||
|
#endif
|
||||||
|
#ifdef EIGEN_VECTORIZE_SSE4_1
|
||||||
|
#include <smmintrin.h>
|
||||||
|
#endif
|
||||||
|
#ifdef EIGEN_VECTORIZE_SSE4_2
|
||||||
|
#include <nmmintrin.h>
|
||||||
|
#endif
|
||||||
|
#if defined(EIGEN_VECTORIZE_AVX) || defined(EIGEN_VECTORIZE_AVX512)
|
||||||
|
#include <immintrin.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
} // end extern "C"
|
||||||
|
#elif defined __VSX__
|
||||||
|
#define EIGEN_VECTORIZE
|
||||||
|
#define EIGEN_VECTORIZE_FMA
|
||||||
|
#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_FMA
|
||||||
|
#define EIGEN_VECTORIZE_ALTIVEC
|
||||||
|
#include <altivec.h>
|
||||||
|
// We need to #undef all these ugly tokens defined in <altivec.h>
|
||||||
|
// => use __vector instead of vector
|
||||||
|
#undef bool
|
||||||
|
#undef vector
|
||||||
|
#undef pixel
|
||||||
|
#elif (defined __ARM_NEON) || (defined __ARM_NEON__)
|
||||||
|
#define EIGEN_VECTORIZE
|
||||||
|
#define EIGEN_VECTORIZE_NEON
|
||||||
|
#include <arm_neon.h>
|
||||||
|
// Enable FMA for ARM.
|
||||||
|
#if defined(__ARM_FEATURE_FMA)
|
||||||
|
#define EIGEN_VECTORIZE_FMA
|
||||||
|
#endif
|
||||||
|
#elif (defined __s390x__ && defined __VEC__)
|
||||||
|
#define EIGEN_VECTORIZE
|
||||||
|
#define EIGEN_VECTORIZE_ZVECTOR
|
||||||
|
#include <vecintrin.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__F16C__) && !defined(EIGEN_COMP_CLANG)
|
||||||
|
// We can use the optimized fp16 to float and float to fp16 conversion routines
|
||||||
|
#define EIGEN_HAS_FP16_C
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined EIGEN_CUDACC
|
||||||
|
#define EIGEN_VECTORIZE_CUDA
|
||||||
|
#include <vector_types.h>
|
||||||
|
#if EIGEN_CUDA_SDK_VER >= 70500
|
||||||
|
#define EIGEN_HAS_CUDA_FP16
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined EIGEN_HAS_CUDA_FP16
|
||||||
|
#include <cuda_runtime_api.h>
|
||||||
|
#include <cuda_fp16.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined _OPENMP) && (!defined EIGEN_DONT_PARALLELIZE)
|
#if (defined _OPENMP) && (!defined EIGEN_DONT_PARALLELIZE)
|
||||||
@@ -83,8 +292,8 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <sstream>
|
||||||
#ifndef EIGEN_NO_IO
|
#ifndef EIGEN_NO_IO
|
||||||
#include <sstream>
|
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#endif
|
#endif
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@@ -94,10 +303,6 @@
|
|||||||
// for min/max:
|
// for min/max:
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#if EIGEN_HAS_CXX11
|
|
||||||
#include <array>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// for std::is_nothrow_move_assignable
|
// for std::is_nothrow_move_assignable
|
||||||
#ifdef EIGEN_INCLUDE_TYPE_TRAITS
|
#ifdef EIGEN_INCLUDE_TYPE_TRAITS
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
@@ -109,30 +314,42 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// required for __cpuid, needs to be included after cmath
|
// required for __cpuid, needs to be included after cmath
|
||||||
// also required for _BitScanReverse on Windows on ARM
|
#if EIGEN_COMP_MSVC && EIGEN_ARCH_i386_OR_x86_64 && !EIGEN_OS_WINCE
|
||||||
#if EIGEN_COMP_MSVC && (EIGEN_ARCH_i386_OR_x86_64 || EIGEN_ARCH_ARM64) && !EIGEN_OS_WINCE
|
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(EIGEN_USE_SYCL)
|
/** \brief Namespace containing all symbols from the %Eigen library. */
|
||||||
#undef min
|
namespace Eigen {
|
||||||
#undef max
|
|
||||||
#undef isnan
|
|
||||||
#undef isinf
|
|
||||||
#undef isfinite
|
|
||||||
#include <CL/sycl.hpp>
|
|
||||||
#include <map>
|
|
||||||
#include <memory>
|
|
||||||
#include <utility>
|
|
||||||
#include <thread>
|
|
||||||
#ifndef EIGEN_SYCL_LOCAL_THREAD_DIM0
|
|
||||||
#define EIGEN_SYCL_LOCAL_THREAD_DIM0 16
|
|
||||||
#endif
|
|
||||||
#ifndef EIGEN_SYCL_LOCAL_THREAD_DIM1
|
|
||||||
#define EIGEN_SYCL_LOCAL_THREAD_DIM1 16
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
inline static const char *SimdInstructionSetsInUse(void) {
|
||||||
|
#if defined(EIGEN_VECTORIZE_AVX512)
|
||||||
|
return "AVX512, FMA, AVX2, AVX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2";
|
||||||
|
#elif 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";
|
||||||
|
#elif defined(EIGEN_VECTORIZE_SSSE3)
|
||||||
|
return "SSE, SSE2, SSE3, SSSE3";
|
||||||
|
#elif defined(EIGEN_VECTORIZE_SSE3)
|
||||||
|
return "SSE, SSE2, SSE3";
|
||||||
|
#elif defined(EIGEN_VECTORIZE_SSE2)
|
||||||
|
return "SSE, SSE2";
|
||||||
|
#elif defined(EIGEN_VECTORIZE_ALTIVEC)
|
||||||
|
return "AltiVec";
|
||||||
|
#elif defined(EIGEN_VECTORIZE_VSX)
|
||||||
|
return "VSX";
|
||||||
|
#elif defined(EIGEN_VECTORIZE_NEON)
|
||||||
|
return "ARM NEON";
|
||||||
|
#elif defined(EIGEN_VECTORIZE_ZVECTOR)
|
||||||
|
return "S390X ZVECTOR";
|
||||||
|
#else
|
||||||
|
return "None";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace Eigen
|
||||||
|
|
||||||
#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
|
#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:
|
// This will generate an error message:
|
||||||
@@ -141,7 +358,7 @@
|
|||||||
|
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
// we use size_t frequently and we'll never remember to prepend it with std:: every time just to
|
// we use size_t frequently and we'll never remember to prepend it with std:: everytime just to
|
||||||
// ensure QNX/QCC support
|
// ensure QNX/QCC support
|
||||||
using std::size_t;
|
using std::size_t;
|
||||||
// gcc 4.6.0 wants std:: for ptrdiff_t
|
// gcc 4.6.0 wants std:: for ptrdiff_t
|
||||||
@@ -165,90 +382,60 @@ using std::ptrdiff_t;
|
|||||||
#include "src/Core/util/StaticAssert.h"
|
#include "src/Core/util/StaticAssert.h"
|
||||||
#include "src/Core/util/XprHelper.h"
|
#include "src/Core/util/XprHelper.h"
|
||||||
#include "src/Core/util/Memory.h"
|
#include "src/Core/util/Memory.h"
|
||||||
#include "src/Core/util/IntegralConstant.h"
|
|
||||||
#include "src/Core/util/SymbolicIndex.h"
|
|
||||||
|
|
||||||
#include "src/Core/NumTraits.h"
|
#include "src/Core/NumTraits.h"
|
||||||
#include "src/Core/MathFunctions.h"
|
#include "src/Core/MathFunctions.h"
|
||||||
#include "src/Core/GenericPacketMath.h"
|
#include "src/Core/GenericPacketMath.h"
|
||||||
#include "src/Core/MathFunctionsImpl.h"
|
#include "src/Core/MathFunctionsImpl.h"
|
||||||
#include "src/Core/arch/Default/ConjHelper.h"
|
#include "src/Core/arch/Default/ConjHelper.h"
|
||||||
// Generic half float support
|
|
||||||
#include "src/Core/arch/Default/Half.h"
|
|
||||||
#include "src/Core/arch/Default/BFloat16.h"
|
|
||||||
#include "src/Core/arch/Default/TypeCasting.h"
|
|
||||||
#include "src/Core/arch/Default/GenericPacketMathFunctionsFwd.h"
|
|
||||||
|
|
||||||
#if defined EIGEN_VECTORIZE_AVX512
|
#if defined EIGEN_VECTORIZE_AVX512
|
||||||
#include "src/Core/arch/SSE/PacketMath.h"
|
#include "src/Core/arch/SSE/PacketMath.h"
|
||||||
#include "src/Core/arch/SSE/TypeCasting.h"
|
|
||||||
#include "src/Core/arch/SSE/Complex.h"
|
|
||||||
#include "src/Core/arch/AVX/PacketMath.h"
|
|
||||||
#include "src/Core/arch/AVX/TypeCasting.h"
|
|
||||||
#include "src/Core/arch/AVX/Complex.h"
|
|
||||||
#include "src/Core/arch/AVX512/PacketMath.h"
|
|
||||||
#include "src/Core/arch/AVX512/TypeCasting.h"
|
|
||||||
#include "src/Core/arch/AVX512/Complex.h"
|
|
||||||
#include "src/Core/arch/SSE/MathFunctions.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/MathFunctions.h"
|
||||||
|
#include "src/Core/arch/AVX512/PacketMath.h"
|
||||||
#include "src/Core/arch/AVX512/MathFunctions.h"
|
#include "src/Core/arch/AVX512/MathFunctions.h"
|
||||||
#elif defined EIGEN_VECTORIZE_AVX
|
#elif defined EIGEN_VECTORIZE_AVX
|
||||||
// Use AVX for floats and doubles, SSE for integers
|
// Use AVX for floats and doubles, SSE for integers
|
||||||
#include "src/Core/arch/SSE/PacketMath.h"
|
#include "src/Core/arch/SSE/PacketMath.h"
|
||||||
#include "src/Core/arch/SSE/TypeCasting.h"
|
|
||||||
#include "src/Core/arch/SSE/Complex.h"
|
#include "src/Core/arch/SSE/Complex.h"
|
||||||
#include "src/Core/arch/AVX/PacketMath.h"
|
|
||||||
#include "src/Core/arch/AVX/TypeCasting.h"
|
|
||||||
#include "src/Core/arch/AVX/Complex.h"
|
|
||||||
#include "src/Core/arch/SSE/MathFunctions.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/MathFunctions.h"
|
||||||
|
#include "src/Core/arch/AVX/Complex.h"
|
||||||
|
#include "src/Core/arch/AVX/TypeCasting.h"
|
||||||
|
#include "src/Core/arch/SSE/TypeCasting.h"
|
||||||
#elif defined EIGEN_VECTORIZE_SSE
|
#elif defined EIGEN_VECTORIZE_SSE
|
||||||
#include "src/Core/arch/SSE/PacketMath.h"
|
#include "src/Core/arch/SSE/PacketMath.h"
|
||||||
#include "src/Core/arch/SSE/TypeCasting.h"
|
|
||||||
#include "src/Core/arch/SSE/MathFunctions.h"
|
#include "src/Core/arch/SSE/MathFunctions.h"
|
||||||
#include "src/Core/arch/SSE/Complex.h"
|
#include "src/Core/arch/SSE/Complex.h"
|
||||||
|
#include "src/Core/arch/SSE/TypeCasting.h"
|
||||||
#elif defined(EIGEN_VECTORIZE_ALTIVEC) || defined(EIGEN_VECTORIZE_VSX)
|
#elif defined(EIGEN_VECTORIZE_ALTIVEC) || defined(EIGEN_VECTORIZE_VSX)
|
||||||
#include "src/Core/arch/AltiVec/PacketMath.h"
|
#include "src/Core/arch/AltiVec/PacketMath.h"
|
||||||
#include "src/Core/arch/AltiVec/MathFunctions.h"
|
#include "src/Core/arch/AltiVec/MathFunctions.h"
|
||||||
#include "src/Core/arch/AltiVec/Complex.h"
|
#include "src/Core/arch/AltiVec/Complex.h"
|
||||||
#elif defined EIGEN_VECTORIZE_NEON
|
#elif defined EIGEN_VECTORIZE_NEON
|
||||||
#include "src/Core/arch/NEON/PacketMath.h"
|
#include "src/Core/arch/NEON/PacketMath.h"
|
||||||
#include "src/Core/arch/NEON/TypeCasting.h"
|
|
||||||
#include "src/Core/arch/NEON/MathFunctions.h"
|
#include "src/Core/arch/NEON/MathFunctions.h"
|
||||||
#include "src/Core/arch/NEON/Complex.h"
|
#include "src/Core/arch/NEON/Complex.h"
|
||||||
#elif defined EIGEN_VECTORIZE_SVE
|
|
||||||
#include "src/Core/arch/SVE/PacketMath.h"
|
|
||||||
#include "src/Core/arch/SVE/TypeCasting.h"
|
|
||||||
#include "src/Core/arch/SVE/MathFunctions.h"
|
|
||||||
#elif defined EIGEN_VECTORIZE_ZVECTOR
|
#elif defined EIGEN_VECTORIZE_ZVECTOR
|
||||||
#include "src/Core/arch/ZVector/PacketMath.h"
|
#include "src/Core/arch/ZVector/PacketMath.h"
|
||||||
#include "src/Core/arch/ZVector/MathFunctions.h"
|
#include "src/Core/arch/ZVector/MathFunctions.h"
|
||||||
#include "src/Core/arch/ZVector/Complex.h"
|
#include "src/Core/arch/ZVector/Complex.h"
|
||||||
#elif defined EIGEN_VECTORIZE_MSA
|
|
||||||
#include "src/Core/arch/MSA/PacketMath.h"
|
|
||||||
#include "src/Core/arch/MSA/MathFunctions.h"
|
|
||||||
#include "src/Core/arch/MSA/Complex.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined EIGEN_VECTORIZE_GPU
|
// Half float support
|
||||||
#include "src/Core/arch/GPU/PacketMath.h"
|
#include "src/Core/arch/CUDA/Half.h"
|
||||||
#include "src/Core/arch/GPU/MathFunctions.h"
|
#include "src/Core/arch/CUDA/PacketMathHalf.h"
|
||||||
#include "src/Core/arch/GPU/TypeCasting.h"
|
#include "src/Core/arch/CUDA/TypeCasting.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(EIGEN_USE_SYCL)
|
#if defined EIGEN_VECTORIZE_CUDA
|
||||||
#include "src/Core/arch/SYCL/SyclMemoryModel.h"
|
#include "src/Core/arch/CUDA/PacketMath.h"
|
||||||
#include "src/Core/arch/SYCL/InteropHeaders.h"
|
#include "src/Core/arch/CUDA/MathFunctions.h"
|
||||||
#if !defined(EIGEN_DONT_VECTORIZE_SYCL)
|
|
||||||
#include "src/Core/arch/SYCL/PacketMath.h"
|
|
||||||
#include "src/Core/arch/SYCL/MathFunctions.h"
|
|
||||||
#include "src/Core/arch/SYCL/TypeCasting.h"
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "src/Core/arch/Default/Settings.h"
|
#include "src/Core/arch/Default/Settings.h"
|
||||||
// This file provides generic implementations valid for scalar as well
|
|
||||||
#include "src/Core/arch/Default/GenericPacketMathFunctions.h"
|
|
||||||
|
|
||||||
#include "src/Core/functors/TernaryFunctors.h"
|
#include "src/Core/functors/TernaryFunctors.h"
|
||||||
#include "src/Core/functors/BinaryFunctors.h"
|
#include "src/Core/functors/BinaryFunctors.h"
|
||||||
@@ -259,16 +446,9 @@ using std::ptrdiff_t;
|
|||||||
|
|
||||||
// Specialized functors to enable the processing of complex numbers
|
// Specialized functors to enable the processing of complex numbers
|
||||||
// on CUDA devices
|
// on CUDA devices
|
||||||
#ifdef EIGEN_CUDACC
|
|
||||||
#include "src/Core/arch/CUDA/Complex.h"
|
#include "src/Core/arch/CUDA/Complex.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "src/Core/util/IndexedViewHelper.h"
|
#include "src/Core/IO.h"
|
||||||
#include "src/Core/util/ReshapedHelper.h"
|
|
||||||
#include "src/Core/ArithmeticSequence.h"
|
|
||||||
#ifndef EIGEN_NO_IO
|
|
||||||
#include "src/Core/IO.h"
|
|
||||||
#endif
|
|
||||||
#include "src/Core/DenseCoeffsBase.h"
|
#include "src/Core/DenseCoeffsBase.h"
|
||||||
#include "src/Core/DenseBase.h"
|
#include "src/Core/DenseBase.h"
|
||||||
#include "src/Core/MatrixBase.h"
|
#include "src/Core/MatrixBase.h"
|
||||||
@@ -309,8 +489,6 @@ using std::ptrdiff_t;
|
|||||||
#include "src/Core/Ref.h"
|
#include "src/Core/Ref.h"
|
||||||
#include "src/Core/Block.h"
|
#include "src/Core/Block.h"
|
||||||
#include "src/Core/VectorBlock.h"
|
#include "src/Core/VectorBlock.h"
|
||||||
#include "src/Core/IndexedView.h"
|
|
||||||
#include "src/Core/Reshaped.h"
|
|
||||||
#include "src/Core/Transpose.h"
|
#include "src/Core/Transpose.h"
|
||||||
#include "src/Core/DiagonalMatrix.h"
|
#include "src/Core/DiagonalMatrix.h"
|
||||||
#include "src/Core/Diagonal.h"
|
#include "src/Core/Diagonal.h"
|
||||||
@@ -347,21 +525,13 @@ using std::ptrdiff_t;
|
|||||||
#include "src/Core/CoreIterators.h"
|
#include "src/Core/CoreIterators.h"
|
||||||
#include "src/Core/ConditionEstimator.h"
|
#include "src/Core/ConditionEstimator.h"
|
||||||
|
|
||||||
#if defined(EIGEN_VECTORIZE_VSX)
|
|
||||||
#include "src/Core/arch/AltiVec/MatrixProduct.h"
|
|
||||||
#elif defined EIGEN_VECTORIZE_NEON
|
|
||||||
#include "src/Core/arch/NEON/GeneralBlockPanelKernel.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "src/Core/BooleanRedux.h"
|
#include "src/Core/BooleanRedux.h"
|
||||||
#include "src/Core/Select.h"
|
#include "src/Core/Select.h"
|
||||||
#include "src/Core/VectorwiseOp.h"
|
#include "src/Core/VectorwiseOp.h"
|
||||||
#include "src/Core/PartialReduxEvaluator.h"
|
|
||||||
#include "src/Core/Random.h"
|
#include "src/Core/Random.h"
|
||||||
#include "src/Core/Replicate.h"
|
#include "src/Core/Replicate.h"
|
||||||
#include "src/Core/Reverse.h"
|
#include "src/Core/Reverse.h"
|
||||||
#include "src/Core/ArrayWrapper.h"
|
#include "src/Core/ArrayWrapper.h"
|
||||||
#include "src/Core/StlIterators.h"
|
|
||||||
|
|
||||||
#ifdef EIGEN_USE_BLAS
|
#ifdef EIGEN_USE_BLAS
|
||||||
#include "src/Core/products/GeneralMatrixMatrix_BLAS.h"
|
#include "src/Core/products/GeneralMatrixMatrix_BLAS.h"
|
||||||
|
|||||||
@@ -58,3 +58,4 @@
|
|||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_EIGENVALUES_MODULE_H
|
#endif // EIGEN_EIGENVALUES_MODULE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
|||||||
@@ -49,11 +49,14 @@
|
|||||||
#include "src/Geometry/AlignedBox.h"
|
#include "src/Geometry/AlignedBox.h"
|
||||||
#include "src/Geometry/Umeyama.h"
|
#include "src/Geometry/Umeyama.h"
|
||||||
|
|
||||||
// Use the SSE optimized version whenever possible.
|
// Use the SSE optimized version whenever possible. At the moment the
|
||||||
#if (defined EIGEN_VECTORIZE_SSE) || (defined EIGEN_VECTORIZE_NEON)
|
// SSE version doesn't compile when AVX is enabled
|
||||||
#include "src/Geometry/arch/Geometry_SIMD.h"
|
#if defined EIGEN_VECTORIZE_SSE && !defined EIGEN_VECTORIZE_AVX
|
||||||
|
#include "src/Geometry/arch/Geometry_SSE.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_GEOMETRY_MODULE_H
|
#endif // EIGEN_GEOMETRY_MODULE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
|
||||||
|
|||||||
@@ -27,3 +27,4 @@
|
|||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_HOUSEHOLDER_MODULE_H
|
#endif // EIGEN_HOUSEHOLDER_MODULE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
|||||||
@@ -29,4 +29,5 @@
|
|||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_JACOBI_MODULE_H
|
#endif // EIGEN_JACOBI_MODULE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// 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_KLUSUPPORT_MODULE_H
|
|
||||||
#define EIGEN_KLUSUPPORT_MODULE_H
|
|
||||||
|
|
||||||
#include <Eigen/SparseCore>
|
|
||||||
|
|
||||||
#include <Eigen/src/Core/util/DisableStupidWarnings.h>
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include <btf.h>
|
|
||||||
#include <klu.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \ingroup Support_modules
|
|
||||||
* \defgroup KLUSupport_Module KLUSupport module
|
|
||||||
*
|
|
||||||
* This module provides an interface to the KLU library which is part of the <a href="http://www.suitesparse.com">suitesparse</a> package.
|
|
||||||
* It provides the following factorization class:
|
|
||||||
* - class KLU: a sparse LU factorization, well-suited for circuit simulation.
|
|
||||||
*
|
|
||||||
* \code
|
|
||||||
* #include <Eigen/KLUSupport>
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* In order to use this module, the klu and btf headers must be accessible from the include paths, and your binary must be linked to the klu library and its dependencies.
|
|
||||||
* The dependencies depend on how umfpack has been compiled.
|
|
||||||
* For a cmake based project, you can use our FindKLU.cmake module to help you in this task.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "src/KLUSupport/KLUSupport.h"
|
|
||||||
|
|
||||||
#include <Eigen/src/Core/util/ReenableStupidWarnings.h>
|
|
||||||
|
|
||||||
#endif // EIGEN_KLUSUPPORT_MODULE_H
|
|
||||||
7
Eigen/LU
7
Eigen/LU
@@ -38,10 +38,13 @@
|
|||||||
#include "src/LU/Determinant.h"
|
#include "src/LU/Determinant.h"
|
||||||
#include "src/LU/InverseImpl.h"
|
#include "src/LU/InverseImpl.h"
|
||||||
|
|
||||||
#if defined EIGEN_VECTORIZE_SSE || defined EIGEN_VECTORIZE_NEON
|
// Use the SSE optimized version whenever possible. At the moment the
|
||||||
#include "src/LU/arch/InverseSize4.h"
|
// 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
|
#endif
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_LU_MODULE_H
|
#endif // EIGEN_LU_MODULE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
|||||||
@@ -63,7 +63,10 @@
|
|||||||
* \endcode
|
* \endcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef EIGEN_MPL2_ONLY
|
||||||
#include "src/OrderingMethods/Amd.h"
|
#include "src/OrderingMethods/Amd.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "src/OrderingMethods/Ordering.h"
|
#include "src/OrderingMethods/Ordering.h"
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ extern "C" {
|
|||||||
* \endcode
|
* \endcode
|
||||||
*
|
*
|
||||||
* In order to use this module, the PaSTiX headers must be accessible from the include paths, and your binary must be linked to the PaSTiX library and its dependencies.
|
* In order to use this module, the PaSTiX headers must be accessible from the include paths, and your binary must be linked to the PaSTiX library and its dependencies.
|
||||||
* This wrapper resuires PaStiX version 5.x compiled without MPI support.
|
|
||||||
* The dependencies depend on how PaSTiX has been compiled.
|
* The dependencies depend on how PaSTiX has been compiled.
|
||||||
* For a cmake based project, you can use our FindPaSTiX.cmake module to help you in this task.
|
* For a cmake based project, you can use our FindPaSTiX.cmake module to help you in this task.
|
||||||
*
|
*
|
||||||
|
|||||||
0
Eigen/PardisoSupport
Normal file → Executable file
0
Eigen/PardisoSupport
Normal file → Executable file
1
Eigen/QR
1
Eigen/QR
@@ -48,3 +48,4 @@
|
|||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_QR_MODULE_H
|
#endif // EIGEN_QR_MODULE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
|||||||
@@ -37,3 +37,4 @@ void *qRealloc(void *ptr, std::size_t size)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // EIGEN_QTMALLOC_MODULE_H
|
#endif // EIGEN_QTMALLOC_MODULE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
|||||||
@@ -48,3 +48,4 @@
|
|||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_SVD_MODULE_H
|
#endif // EIGEN_SVD_MODULE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
|||||||
@@ -25,7 +25,9 @@
|
|||||||
|
|
||||||
#include "SparseCore"
|
#include "SparseCore"
|
||||||
#include "OrderingMethods"
|
#include "OrderingMethods"
|
||||||
|
#ifndef EIGEN_MPL2_ONLY
|
||||||
#include "SparseCholesky"
|
#include "SparseCholesky"
|
||||||
|
#endif
|
||||||
#include "SparseLU"
|
#include "SparseLU"
|
||||||
#include "SparseQR"
|
#include "SparseQR"
|
||||||
#include "IterativeLinearSolvers"
|
#include "IterativeLinearSolvers"
|
||||||
|
|||||||
@@ -30,8 +30,16 @@
|
|||||||
* \endcode
|
* \endcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef EIGEN_MPL2_ONLY
|
||||||
|
#error The SparseCholesky module has nothing to offer in MPL2 only mode
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "src/SparseCholesky/SimplicialCholesky.h"
|
#include "src/SparseCholesky/SimplicialCholesky.h"
|
||||||
|
|
||||||
|
#ifndef EIGEN_MPL2_ONLY
|
||||||
#include "src/SparseCholesky/SimplicialCholesky_impl.h"
|
#include "src/SparseCholesky/SimplicialCholesky_impl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_SPARSECHOLESKY_MODULE_H
|
#endif // EIGEN_SPARSECHOLESKY_MODULE_H
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
// Ordering interface
|
// Ordering interface
|
||||||
#include "OrderingMethods"
|
#include "OrderingMethods"
|
||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
#include "src/SparseLU/SparseLU_gemm_kernel.h"
|
||||||
|
|
||||||
#include "src/SparseLU/SparseLU_Structs.h"
|
#include "src/SparseLU/SparseLU_Structs.h"
|
||||||
#include "src/SparseLU/SparseLU_SupernodalMatrix.h"
|
#include "src/SparseLU/SparseLU_SupernodalMatrix.h"
|
||||||
@@ -43,6 +43,4 @@
|
|||||||
#include "src/SparseLU/SparseLU_Utils.h"
|
#include "src/SparseLU/SparseLU_Utils.h"
|
||||||
#include "src/SparseLU/SparseLU.h"
|
#include "src/SparseLU/SparseLU.h"
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
|
||||||
|
|
||||||
#endif // EIGEN_SPARSELU_MODULE_H
|
#endif // EIGEN_SPARSELU_MODULE_H
|
||||||
|
|||||||
@@ -16,15 +16,6 @@
|
|||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
template<typename _MatrixType, int _UpLo> struct traits<LDLT<_MatrixType, _UpLo> >
|
|
||||||
: traits<_MatrixType>
|
|
||||||
{
|
|
||||||
typedef MatrixXpr XprKind;
|
|
||||||
typedef SolverStorage StorageKind;
|
|
||||||
typedef int StorageIndex;
|
|
||||||
enum { Flags = 0 };
|
|
||||||
};
|
|
||||||
|
|
||||||
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
|
// PositiveSemiDef means positive semi-definite and non-zero; same for NegativeSemiDef
|
||||||
@@ -45,7 +36,7 @@ namespace internal {
|
|||||||
* matrix \f$ A \f$ such that \f$ A = P^TLDL^*P \f$, where P is a permutation matrix, L
|
* matrix \f$ A \f$ such that \f$ A = P^TLDL^*P \f$, where P is a permutation matrix, L
|
||||||
* is lower triangular with a unit diagonal and D is a diagonal matrix.
|
* is lower triangular with a unit diagonal and D is a diagonal matrix.
|
||||||
*
|
*
|
||||||
* The decomposition uses pivoting to ensure stability, so that D will have
|
* The decomposition uses pivoting to ensure stability, so that L will have
|
||||||
* zeros in the bottom right rank(A) - n submatrix. Avoiding the square root
|
* zeros in the bottom right rank(A) - n submatrix. Avoiding the square root
|
||||||
* on D also stabilizes the computation.
|
* on D also stabilizes the computation.
|
||||||
*
|
*
|
||||||
@@ -57,19 +48,20 @@ namespace internal {
|
|||||||
* \sa MatrixBase::ldlt(), SelfAdjointView::ldlt(), class LLT
|
* \sa MatrixBase::ldlt(), SelfAdjointView::ldlt(), class LLT
|
||||||
*/
|
*/
|
||||||
template<typename _MatrixType, int _UpLo> class LDLT
|
template<typename _MatrixType, int _UpLo> class LDLT
|
||||||
: public SolverBase<LDLT<_MatrixType, _UpLo> >
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef _MatrixType MatrixType;
|
typedef _MatrixType MatrixType;
|
||||||
typedef SolverBase<LDLT> Base;
|
|
||||||
friend class SolverBase<LDLT>;
|
|
||||||
|
|
||||||
EIGEN_GENERIC_PUBLIC_INTERFACE(LDLT)
|
|
||||||
enum {
|
enum {
|
||||||
|
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
|
||||||
|
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
|
||||||
MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
|
MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
|
||||||
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
|
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
|
||||||
UpLo = _UpLo
|
UpLo = _UpLo
|
||||||
};
|
};
|
||||||
|
typedef typename MatrixType::Scalar Scalar;
|
||||||
|
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
|
||||||
|
typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
|
||||||
|
typedef typename MatrixType::StorageIndex StorageIndex;
|
||||||
typedef Matrix<Scalar, RowsAtCompileTime, 1, 0, MaxRowsAtCompileTime, 1> TmpMatrixType;
|
typedef Matrix<Scalar, RowsAtCompileTime, 1, 0, MaxRowsAtCompileTime, 1> TmpMatrixType;
|
||||||
|
|
||||||
typedef Transpositions<RowsAtCompileTime, MaxRowsAtCompileTime> TranspositionType;
|
typedef Transpositions<RowsAtCompileTime, MaxRowsAtCompileTime> TranspositionType;
|
||||||
@@ -188,7 +180,6 @@ template<typename _MatrixType, int _UpLo> class LDLT
|
|||||||
return m_sign == internal::NegativeSemiDef || m_sign == internal::ZeroSign;
|
return m_sign == internal::NegativeSemiDef || m_sign == internal::ZeroSign;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
/** \returns a solution x of \f$ A x = b \f$ using the current decomposition of A.
|
/** \returns a solution x of \f$ A x = b \f$ using the current decomposition of A.
|
||||||
*
|
*
|
||||||
* This function also supports in-place solves using the syntax <tt>x = decompositionObject.solve(x)</tt> .
|
* This function also supports in-place solves using the syntax <tt>x = decompositionObject.solve(x)</tt> .
|
||||||
@@ -200,14 +191,19 @@ template<typename _MatrixType, int _UpLo> class LDLT
|
|||||||
* \f$ L^* y_4 = y_3 \f$ and \f$ P x = y_4 \f$ in succession. If the matrix \f$ A \f$ is singular, then
|
* \f$ L^* y_4 = y_3 \f$ and \f$ P x = y_4 \f$ in succession. If the matrix \f$ A \f$ is singular, then
|
||||||
* \f$ D \f$ will also be singular (all the other matrices are invertible). In that case, the
|
* \f$ D \f$ will also be singular (all the other matrices are invertible). In that case, the
|
||||||
* least-square solution of \f$ D y_3 = y_2 \f$ is computed. This does not mean that this function
|
* 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$ if \f$ A \f$ is singular.
|
* computes the least-square solution of \f$ A x = b \f$ is \f$ A \f$ is singular.
|
||||||
*
|
*
|
||||||
* \sa MatrixBase::ldlt(), SelfAdjointView::ldlt()
|
* \sa MatrixBase::ldlt(), SelfAdjointView::ldlt()
|
||||||
*/
|
*/
|
||||||
template<typename Rhs>
|
template<typename Rhs>
|
||||||
inline const Solve<LDLT, Rhs>
|
inline const Solve<LDLT, Rhs>
|
||||||
solve(const MatrixBase<Rhs>& b) const;
|
solve(const MatrixBase<Rhs>& b) const
|
||||||
#endif
|
{
|
||||||
|
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 Solve<LDLT, Rhs>(*this, b.derived());
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
bool solveInPlace(MatrixBase<Derived> &bAndX) const;
|
bool solveInPlace(MatrixBase<Derived> &bAndX) const;
|
||||||
@@ -246,12 +242,12 @@ template<typename _MatrixType, int _UpLo> class LDLT
|
|||||||
*/
|
*/
|
||||||
const LDLT& adjoint() const { return *this; };
|
const LDLT& adjoint() const { return *this; };
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
|
inline Index rows() const { return m_matrix.rows(); }
|
||||||
EIGEN_DEVICE_FUNC inline EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
|
inline Index cols() const { return m_matrix.cols(); }
|
||||||
|
|
||||||
/** \brief Reports whether previous computation was successful.
|
/** \brief Reports whether previous computation was successful.
|
||||||
*
|
*
|
||||||
* \returns \c Success if computation was successful,
|
* \returns \c Success if computation was succesful,
|
||||||
* \c NumericalIssue if the factorization failed because of a zero pivot.
|
* \c NumericalIssue if the factorization failed because of a zero pivot.
|
||||||
*/
|
*/
|
||||||
ComputationInfo info() const
|
ComputationInfo info() const
|
||||||
@@ -262,10 +258,8 @@ template<typename _MatrixType, int _UpLo> class LDLT
|
|||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
template<typename RhsType, typename DstType>
|
template<typename RhsType, typename DstType>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
void _solve_impl(const RhsType &rhs, DstType &dst) const;
|
void _solve_impl(const RhsType &rhs, DstType &dst) const;
|
||||||
|
|
||||||
template<bool Conjugate, typename RhsType, typename DstType>
|
|
||||||
void _solve_impl_transposed(const RhsType &rhs, DstType &dst) const;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -564,24 +558,16 @@ LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::rankUpdate(const MatrixBase<Deri
|
|||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
template<typename _MatrixType, int _UpLo>
|
template<typename _MatrixType, int _UpLo>
|
||||||
template<typename RhsType, typename DstType>
|
template<typename RhsType, typename DstType>
|
||||||
void LDLT<_MatrixType,_UpLo>::_solve_impl(const RhsType &rhs, DstType &dst) const
|
EIGEN_DEVICE_FUNC void LDLT<_MatrixType,_UpLo>::_solve_impl(const RhsType &rhs, DstType &dst) const
|
||||||
{
|
|
||||||
_solve_impl_transposed<true>(rhs, dst);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename _MatrixType,int _UpLo>
|
|
||||||
template<bool Conjugate, typename RhsType, typename DstType>
|
|
||||||
void LDLT<_MatrixType,_UpLo>::_solve_impl_transposed(const RhsType &rhs, DstType &dst) const
|
|
||||||
{
|
{
|
||||||
|
eigen_assert(rhs.rows() == rows());
|
||||||
// dst = P b
|
// dst = P b
|
||||||
dst = m_transpositions * rhs;
|
dst = m_transpositions * rhs;
|
||||||
|
|
||||||
// dst = L^-1 (P b)
|
// dst = L^-1 (P b)
|
||||||
// dst = L^-*T (P b)
|
matrixL().solveInPlace(dst);
|
||||||
matrixL().template conjugateIf<!Conjugate>().solveInPlace(dst);
|
|
||||||
|
|
||||||
// dst = D^-* (L^-1 P b)
|
// dst = D^-1 (L^-1 P b)
|
||||||
// dst = D^-1 (L^-*T P b)
|
|
||||||
// more precisely, use pseudo-inverse of D (see bug 241)
|
// more precisely, use pseudo-inverse of D (see bug 241)
|
||||||
using std::abs;
|
using std::abs;
|
||||||
const typename Diagonal<const MatrixType>::RealReturnType vecD(vectorD());
|
const typename Diagonal<const MatrixType>::RealReturnType vecD(vectorD());
|
||||||
@@ -593,6 +579,7 @@ void LDLT<_MatrixType,_UpLo>::_solve_impl_transposed(const RhsType &rhs, DstType
|
|||||||
// Moreover, Lapack's xSYTRS routines use 0 for the tolerance.
|
// Moreover, Lapack's xSYTRS routines use 0 for the tolerance.
|
||||||
// Using numeric_limits::min() gives us more robustness to denormals.
|
// Using numeric_limits::min() gives us more robustness to denormals.
|
||||||
RealScalar tolerance = (std::numeric_limits<RealScalar>::min)();
|
RealScalar tolerance = (std::numeric_limits<RealScalar>::min)();
|
||||||
|
|
||||||
for (Index i = 0; i < vecD.size(); ++i)
|
for (Index i = 0; i < vecD.size(); ++i)
|
||||||
{
|
{
|
||||||
if(abs(vecD(i)) > tolerance)
|
if(abs(vecD(i)) > tolerance)
|
||||||
@@ -601,12 +588,10 @@ void LDLT<_MatrixType,_UpLo>::_solve_impl_transposed(const RhsType &rhs, DstType
|
|||||||
dst.row(i).setZero();
|
dst.row(i).setZero();
|
||||||
}
|
}
|
||||||
|
|
||||||
// dst = L^-* (D^-* L^-1 P b)
|
// dst = L^-T (D^-1 L^-1 P b)
|
||||||
// dst = L^-T (D^-1 L^-*T P b)
|
matrixU().solveInPlace(dst);
|
||||||
matrixL().transpose().template conjugateIf<Conjugate>().solveInPlace(dst);
|
|
||||||
|
|
||||||
// dst = P^T (L^-* D^-* L^-1 P b) = A^-1 b
|
// dst = P^-1 (L^-T D^-1 L^-1 P b) = A^-1 b
|
||||||
// dst = P^-T (L^-T D^-1 L^-*T P b) = A^-1 b
|
|
||||||
dst = m_transpositions.transpose() * dst;
|
dst = m_transpositions.transpose() * dst;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -13,16 +13,6 @@
|
|||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
namespace internal{
|
namespace internal{
|
||||||
|
|
||||||
template<typename _MatrixType, int _UpLo> struct traits<LLT<_MatrixType, _UpLo> >
|
|
||||||
: traits<_MatrixType>
|
|
||||||
{
|
|
||||||
typedef MatrixXpr XprKind;
|
|
||||||
typedef SolverStorage StorageKind;
|
|
||||||
typedef int StorageIndex;
|
|
||||||
enum { Flags = 0 };
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename MatrixType, int UpLo> struct LLT_Traits;
|
template<typename MatrixType, int UpLo> struct LLT_Traits;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,17 +54,18 @@ template<typename MatrixType, int UpLo> struct LLT_Traits;
|
|||||||
* \sa MatrixBase::llt(), SelfAdjointView::llt(), class LDLT
|
* \sa MatrixBase::llt(), SelfAdjointView::llt(), class LDLT
|
||||||
*/
|
*/
|
||||||
template<typename _MatrixType, int _UpLo> class LLT
|
template<typename _MatrixType, int _UpLo> class LLT
|
||||||
: public SolverBase<LLT<_MatrixType, _UpLo> >
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef _MatrixType MatrixType;
|
typedef _MatrixType MatrixType;
|
||||||
typedef SolverBase<LLT> Base;
|
|
||||||
friend class SolverBase<LLT>;
|
|
||||||
|
|
||||||
EIGEN_GENERIC_PUBLIC_INTERFACE(LLT)
|
|
||||||
enum {
|
enum {
|
||||||
|
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
|
||||||
|
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
|
||||||
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
|
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
|
||||||
};
|
};
|
||||||
|
typedef typename MatrixType::Scalar Scalar;
|
||||||
|
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
|
||||||
|
typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
|
||||||
|
typedef typename MatrixType::StorageIndex StorageIndex;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PacketSize = internal::packet_traits<Scalar>::size,
|
PacketSize = internal::packet_traits<Scalar>::size,
|
||||||
@@ -109,7 +100,7 @@ template<typename _MatrixType, int _UpLo> class LLT
|
|||||||
compute(matrix.derived());
|
compute(matrix.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Constructs a LLT factorization from a given matrix
|
/** \brief Constructs a LDLT factorization from a given matrix
|
||||||
*
|
*
|
||||||
* This overloaded constructor is provided for \link InplaceDecomposition inplace decomposition \endlink when
|
* This overloaded constructor is provided for \link InplaceDecomposition inplace decomposition \endlink when
|
||||||
* \c MatrixType is a Eigen::Ref.
|
* \c MatrixType is a Eigen::Ref.
|
||||||
@@ -138,7 +129,6 @@ template<typename _MatrixType, int _UpLo> class LLT
|
|||||||
return Traits::getL(m_matrix);
|
return Traits::getL(m_matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
|
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
|
||||||
*
|
*
|
||||||
* Since this LLT class assumes anyway that the matrix A is invertible, the solution
|
* Since this LLT class assumes anyway that the matrix A is invertible, the solution
|
||||||
@@ -151,8 +141,13 @@ template<typename _MatrixType, int _UpLo> class LLT
|
|||||||
*/
|
*/
|
||||||
template<typename Rhs>
|
template<typename Rhs>
|
||||||
inline const Solve<LLT, Rhs>
|
inline const Solve<LLT, Rhs>
|
||||||
solve(const MatrixBase<Rhs>& b) const;
|
solve(const MatrixBase<Rhs>& b) const
|
||||||
#endif
|
{
|
||||||
|
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 Solve<LLT, Rhs>(*this, b.derived());
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
void solveInPlace(const MatrixBase<Derived> &bAndX) const;
|
void solveInPlace(const MatrixBase<Derived> &bAndX) const;
|
||||||
@@ -185,7 +180,7 @@ template<typename _MatrixType, int _UpLo> class LLT
|
|||||||
|
|
||||||
/** \brief Reports whether previous computation was successful.
|
/** \brief Reports whether previous computation was successful.
|
||||||
*
|
*
|
||||||
* \returns \c Success if computation was successful,
|
* \returns \c Success if computation was succesful,
|
||||||
* \c NumericalIssue if the matrix.appears not to be positive definite.
|
* \c NumericalIssue if the matrix.appears not to be positive definite.
|
||||||
*/
|
*/
|
||||||
ComputationInfo info() const
|
ComputationInfo info() const
|
||||||
@@ -199,20 +194,18 @@ template<typename _MatrixType, int _UpLo> class LLT
|
|||||||
* This method is provided for compatibility with other matrix decompositions, thus enabling generic code such as:
|
* This method is provided for compatibility with other matrix decompositions, thus enabling generic code such as:
|
||||||
* \code x = decomposition.adjoint().solve(b) \endcode
|
* \code x = decomposition.adjoint().solve(b) \endcode
|
||||||
*/
|
*/
|
||||||
const LLT& adjoint() const EIGEN_NOEXCEPT { return *this; };
|
const LLT& adjoint() const { return *this; };
|
||||||
|
|
||||||
inline EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
|
inline Index rows() const { return m_matrix.rows(); }
|
||||||
inline EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
|
inline Index cols() const { return m_matrix.cols(); }
|
||||||
|
|
||||||
template<typename VectorType>
|
template<typename VectorType>
|
||||||
LLT & rankUpdate(const VectorType& vec, const RealScalar& sigma = 1);
|
LLT rankUpdate(const VectorType& vec, const RealScalar& sigma = 1);
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
template<typename RhsType, typename DstType>
|
template<typename RhsType, typename DstType>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
void _solve_impl(const RhsType &rhs, DstType &dst) const;
|
void _solve_impl(const RhsType &rhs, DstType &dst) const;
|
||||||
|
|
||||||
template<bool Conjugate, typename RhsType, typename DstType>
|
|
||||||
void _solve_impl_transposed(const RhsType &rhs, DstType &dst) const;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -466,7 +459,7 @@ LLT<MatrixType,_UpLo>& LLT<MatrixType,_UpLo>::compute(const EigenBase<InputType>
|
|||||||
*/
|
*/
|
||||||
template<typename _MatrixType, int _UpLo>
|
template<typename _MatrixType, int _UpLo>
|
||||||
template<typename VectorType>
|
template<typename VectorType>
|
||||||
LLT<_MatrixType,_UpLo> & LLT<_MatrixType,_UpLo>::rankUpdate(const VectorType& v, const RealScalar& sigma)
|
LLT<_MatrixType,_UpLo> LLT<_MatrixType,_UpLo>::rankUpdate(const VectorType& v, const RealScalar& sigma)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorType);
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorType);
|
||||||
eigen_assert(v.size()==m_matrix.cols());
|
eigen_assert(v.size()==m_matrix.cols());
|
||||||
@@ -482,19 +475,10 @@ LLT<_MatrixType,_UpLo> & LLT<_MatrixType,_UpLo>::rankUpdate(const VectorType& v,
|
|||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
template<typename _MatrixType,int _UpLo>
|
template<typename _MatrixType,int _UpLo>
|
||||||
template<typename RhsType, typename DstType>
|
template<typename RhsType, typename DstType>
|
||||||
void LLT<_MatrixType,_UpLo>::_solve_impl(const RhsType &rhs, DstType &dst) const
|
EIGEN_DEVICE_FUNC void LLT<_MatrixType,_UpLo>::_solve_impl(const RhsType &rhs, DstType &dst) const
|
||||||
{
|
{
|
||||||
_solve_impl_transposed<true>(rhs, dst);
|
dst = rhs;
|
||||||
}
|
solveInPlace(dst);
|
||||||
|
|
||||||
template<typename _MatrixType,int _UpLo>
|
|
||||||
template<bool Conjugate, typename RhsType, typename DstType>
|
|
||||||
void LLT<_MatrixType,_UpLo>::_solve_impl_transposed(const RhsType &rhs, DstType &dst) const
|
|
||||||
{
|
|
||||||
dst = rhs;
|
|
||||||
|
|
||||||
matrixL().template conjugateIf<!Conjugate>().solveInPlace(dst);
|
|
||||||
matrixU().template conjugateIf<!Conjugate>().solveInPlace(dst);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ template<> struct cholmod_configure_matrix<std::complex<double> > {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Other scalar types are not yet supported by Cholmod
|
// Other scalar types are not yet suppotred by Cholmod
|
||||||
// template<> struct cholmod_configure_matrix<float> {
|
// template<> struct cholmod_configure_matrix<float> {
|
||||||
// template<typename CholmodType>
|
// template<typename CholmodType>
|
||||||
// static void run(CholmodType& mat) {
|
// static void run(CholmodType& mat) {
|
||||||
@@ -84,7 +84,7 @@ cholmod_sparse viewAsCholmod(Ref<SparseMatrix<_Scalar,_Options,_StorageIndex> >
|
|||||||
{
|
{
|
||||||
res.itype = CHOLMOD_INT;
|
res.itype = CHOLMOD_INT;
|
||||||
}
|
}
|
||||||
else if (internal::is_same<_StorageIndex,SuiteSparse_long>::value)
|
else if (internal::is_same<_StorageIndex,long>::value)
|
||||||
{
|
{
|
||||||
res.itype = CHOLMOD_LONG;
|
res.itype = CHOLMOD_LONG;
|
||||||
}
|
}
|
||||||
@@ -124,9 +124,6 @@ cholmod_sparse viewAsCholmod(const SparseSelfAdjointView<const SparseMatrix<_Sca
|
|||||||
|
|
||||||
if(UpLo==Upper) res.stype = 1;
|
if(UpLo==Upper) res.stype = 1;
|
||||||
if(UpLo==Lower) res.stype = -1;
|
if(UpLo==Lower) res.stype = -1;
|
||||||
// swap stype for rowmajor matrices (only works for real matrices)
|
|
||||||
EIGEN_STATIC_ASSERT((_Options & RowMajorBit) == 0 || NumTraits<_Scalar>::IsComplex == 0, THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
|
|
||||||
if(_Options & RowMajorBit) res.stype *=-1;
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -162,44 +159,6 @@ MappedSparseMatrix<Scalar,Flags,StorageIndex> viewAsEigen(cholmod_sparse& cm)
|
|||||||
static_cast<StorageIndex*>(cm.p), static_cast<StorageIndex*>(cm.i),static_cast<Scalar*>(cm.x) );
|
static_cast<StorageIndex*>(cm.p), static_cast<StorageIndex*>(cm.i),static_cast<Scalar*>(cm.x) );
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
// template specializations for int and long that call the correct cholmod method
|
|
||||||
|
|
||||||
#define EIGEN_CHOLMOD_SPECIALIZE0(ret, name) \
|
|
||||||
template<typename _StorageIndex> inline ret cm_ ## name (cholmod_common &Common) { return cholmod_ ## name (&Common); } \
|
|
||||||
template<> inline ret cm_ ## name<SuiteSparse_long> (cholmod_common &Common) { return cholmod_l_ ## name (&Common); }
|
|
||||||
|
|
||||||
#define EIGEN_CHOLMOD_SPECIALIZE1(ret, name, t1, a1) \
|
|
||||||
template<typename _StorageIndex> inline ret cm_ ## name (t1& a1, cholmod_common &Common) { return cholmod_ ## name (&a1, &Common); } \
|
|
||||||
template<> inline ret cm_ ## name<SuiteSparse_long> (t1& a1, cholmod_common &Common) { return cholmod_l_ ## name (&a1, &Common); }
|
|
||||||
|
|
||||||
EIGEN_CHOLMOD_SPECIALIZE0(int, start)
|
|
||||||
EIGEN_CHOLMOD_SPECIALIZE0(int, finish)
|
|
||||||
|
|
||||||
EIGEN_CHOLMOD_SPECIALIZE1(int, free_factor, cholmod_factor*, L)
|
|
||||||
EIGEN_CHOLMOD_SPECIALIZE1(int, free_dense, cholmod_dense*, X)
|
|
||||||
EIGEN_CHOLMOD_SPECIALIZE1(int, free_sparse, cholmod_sparse*, A)
|
|
||||||
|
|
||||||
EIGEN_CHOLMOD_SPECIALIZE1(cholmod_factor*, analyze, cholmod_sparse, A)
|
|
||||||
|
|
||||||
template<typename _StorageIndex> inline cholmod_dense* cm_solve (int sys, cholmod_factor& L, cholmod_dense& B, cholmod_common &Common) { return cholmod_solve (sys, &L, &B, &Common); }
|
|
||||||
template<> inline cholmod_dense* cm_solve<SuiteSparse_long> (int sys, cholmod_factor& L, cholmod_dense& B, cholmod_common &Common) { return cholmod_l_solve (sys, &L, &B, &Common); }
|
|
||||||
|
|
||||||
template<typename _StorageIndex> inline cholmod_sparse* cm_spsolve (int sys, cholmod_factor& L, cholmod_sparse& B, cholmod_common &Common) { return cholmod_spsolve (sys, &L, &B, &Common); }
|
|
||||||
template<> inline cholmod_sparse* cm_spsolve<SuiteSparse_long> (int sys, cholmod_factor& L, cholmod_sparse& B, cholmod_common &Common) { return cholmod_l_spsolve (sys, &L, &B, &Common); }
|
|
||||||
|
|
||||||
template<typename _StorageIndex>
|
|
||||||
inline int cm_factorize_p (cholmod_sparse* A, double beta[2], _StorageIndex* fset, std::size_t fsize, cholmod_factor* L, cholmod_common &Common) { return cholmod_factorize_p (A, beta, fset, fsize, L, &Common); }
|
|
||||||
template<>
|
|
||||||
inline int cm_factorize_p<SuiteSparse_long> (cholmod_sparse* A, double beta[2], SuiteSparse_long* fset, std::size_t fsize, cholmod_factor* L, cholmod_common &Common) { return cholmod_l_factorize_p (A, beta, fset, fsize, L, &Common); }
|
|
||||||
|
|
||||||
#undef EIGEN_CHOLMOD_SPECIALIZE0
|
|
||||||
#undef EIGEN_CHOLMOD_SPECIALIZE1
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
|
|
||||||
enum CholmodMode {
|
enum CholmodMode {
|
||||||
CholmodAuto, CholmodSimplicialLLt, CholmodSupernodalLLt, CholmodLDLt
|
CholmodAuto, CholmodSimplicialLLt, CholmodSupernodalLLt, CholmodLDLt
|
||||||
};
|
};
|
||||||
@@ -236,7 +195,7 @@ class CholmodBase : public SparseSolverBase<Derived>
|
|||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT((internal::is_same<double,RealScalar>::value), CHOLMOD_SUPPORTS_DOUBLE_PRECISION_ONLY);
|
EIGEN_STATIC_ASSERT((internal::is_same<double,RealScalar>::value), CHOLMOD_SUPPORTS_DOUBLE_PRECISION_ONLY);
|
||||||
m_shiftOffset[0] = m_shiftOffset[1] = 0.0;
|
m_shiftOffset[0] = m_shiftOffset[1] = 0.0;
|
||||||
internal::cm_start<StorageIndex>(m_cholmod);
|
cholmod_start(&m_cholmod);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit CholmodBase(const MatrixType& matrix)
|
explicit CholmodBase(const MatrixType& matrix)
|
||||||
@@ -244,15 +203,15 @@ class CholmodBase : public SparseSolverBase<Derived>
|
|||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT((internal::is_same<double,RealScalar>::value), CHOLMOD_SUPPORTS_DOUBLE_PRECISION_ONLY);
|
EIGEN_STATIC_ASSERT((internal::is_same<double,RealScalar>::value), CHOLMOD_SUPPORTS_DOUBLE_PRECISION_ONLY);
|
||||||
m_shiftOffset[0] = m_shiftOffset[1] = 0.0;
|
m_shiftOffset[0] = m_shiftOffset[1] = 0.0;
|
||||||
internal::cm_start<StorageIndex>(m_cholmod);
|
cholmod_start(&m_cholmod);
|
||||||
compute(matrix);
|
compute(matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
~CholmodBase()
|
~CholmodBase()
|
||||||
{
|
{
|
||||||
if(m_cholmodFactor)
|
if(m_cholmodFactor)
|
||||||
internal::cm_free_factor<StorageIndex>(m_cholmodFactor, m_cholmod);
|
cholmod_free_factor(&m_cholmodFactor, &m_cholmod);
|
||||||
internal::cm_finish<StorageIndex>(m_cholmod);
|
cholmod_finish(&m_cholmod);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline StorageIndex cols() const { return internal::convert_index<StorageIndex, Index>(m_cholmodFactor->n); }
|
inline StorageIndex cols() const { return internal::convert_index<StorageIndex, Index>(m_cholmodFactor->n); }
|
||||||
@@ -260,7 +219,7 @@ class CholmodBase : public SparseSolverBase<Derived>
|
|||||||
|
|
||||||
/** \brief Reports whether previous computation was successful.
|
/** \brief Reports whether previous computation was successful.
|
||||||
*
|
*
|
||||||
* \returns \c Success if computation was successful,
|
* \returns \c Success if computation was succesful,
|
||||||
* \c NumericalIssue if the matrix.appears to be negative.
|
* \c NumericalIssue if the matrix.appears to be negative.
|
||||||
*/
|
*/
|
||||||
ComputationInfo info() const
|
ComputationInfo info() const
|
||||||
@@ -287,11 +246,11 @@ class CholmodBase : public SparseSolverBase<Derived>
|
|||||||
{
|
{
|
||||||
if(m_cholmodFactor)
|
if(m_cholmodFactor)
|
||||||
{
|
{
|
||||||
internal::cm_free_factor<StorageIndex>(m_cholmodFactor, m_cholmod);
|
cholmod_free_factor(&m_cholmodFactor, &m_cholmod);
|
||||||
m_cholmodFactor = 0;
|
m_cholmodFactor = 0;
|
||||||
}
|
}
|
||||||
cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView<UpLo>());
|
cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView<UpLo>());
|
||||||
m_cholmodFactor = internal::cm_analyze<StorageIndex>(A, m_cholmod);
|
m_cholmodFactor = cholmod_analyze(&A, &m_cholmod);
|
||||||
|
|
||||||
this->m_isInitialized = true;
|
this->m_isInitialized = true;
|
||||||
this->m_info = Success;
|
this->m_info = Success;
|
||||||
@@ -309,7 +268,7 @@ class CholmodBase : public SparseSolverBase<Derived>
|
|||||||
{
|
{
|
||||||
eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
|
eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
|
||||||
cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView<UpLo>());
|
cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView<UpLo>());
|
||||||
internal::cm_factorize_p<StorageIndex>(&A, m_shiftOffset, 0, 0, m_cholmodFactor, m_cholmod);
|
cholmod_factorize_p(&A, m_shiftOffset, 0, 0, m_cholmodFactor, &m_cholmod);
|
||||||
|
|
||||||
// If the factorization failed, minor is the column at which it did. On success minor == n.
|
// If the factorization failed, minor is the column at which it did. On success minor == n.
|
||||||
this->m_info = (m_cholmodFactor->minor == m_cholmodFactor->n ? Success : NumericalIssue);
|
this->m_info = (m_cholmodFactor->minor == m_cholmodFactor->n ? Success : NumericalIssue);
|
||||||
@@ -330,20 +289,19 @@ class CholmodBase : public SparseSolverBase<Derived>
|
|||||||
EIGEN_UNUSED_VARIABLE(size);
|
EIGEN_UNUSED_VARIABLE(size);
|
||||||
eigen_assert(size==b.rows());
|
eigen_assert(size==b.rows());
|
||||||
|
|
||||||
// Cholmod needs column-major storage without inner-stride, which corresponds to the default behavior of Ref.
|
// Cholmod needs column-major stoarge without inner-stride, which corresponds to the default behavior of Ref.
|
||||||
Ref<const Matrix<typename Rhs::Scalar,Dynamic,Dynamic,ColMajor> > b_ref(b.derived());
|
Ref<const Matrix<typename Rhs::Scalar,Dynamic,Dynamic,ColMajor> > b_ref(b.derived());
|
||||||
|
|
||||||
cholmod_dense b_cd = viewAsCholmod(b_ref);
|
cholmod_dense b_cd = viewAsCholmod(b_ref);
|
||||||
cholmod_dense* x_cd = internal::cm_solve<StorageIndex>(CHOLMOD_A, *m_cholmodFactor, b_cd, m_cholmod);
|
cholmod_dense* x_cd = cholmod_solve(CHOLMOD_A, m_cholmodFactor, &b_cd, &m_cholmod);
|
||||||
if(!x_cd)
|
if(!x_cd)
|
||||||
{
|
{
|
||||||
this->m_info = NumericalIssue;
|
this->m_info = NumericalIssue;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO optimize this copy by swapping when possible (be careful with alignment, etc.)
|
// TODO optimize this copy by swapping when possible (be careful with alignment, etc.)
|
||||||
// NOTE Actually, the copy can be avoided by calling cholmod_solve2 instead of cholmod_solve
|
|
||||||
dest = Matrix<Scalar,Dest::RowsAtCompileTime,Dest::ColsAtCompileTime>::Map(reinterpret_cast<Scalar*>(x_cd->x),b.rows(),b.cols());
|
dest = Matrix<Scalar,Dest::RowsAtCompileTime,Dest::ColsAtCompileTime>::Map(reinterpret_cast<Scalar*>(x_cd->x),b.rows(),b.cols());
|
||||||
internal::cm_free_dense<StorageIndex>(x_cd, m_cholmod);
|
cholmod_free_dense(&x_cd, &m_cholmod);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \internal */
|
/** \internal */
|
||||||
@@ -358,16 +316,15 @@ class CholmodBase : public SparseSolverBase<Derived>
|
|||||||
// note: cs stands for Cholmod Sparse
|
// note: cs stands for Cholmod Sparse
|
||||||
Ref<SparseMatrix<typename RhsDerived::Scalar,ColMajor,typename RhsDerived::StorageIndex> > b_ref(b.const_cast_derived());
|
Ref<SparseMatrix<typename RhsDerived::Scalar,ColMajor,typename RhsDerived::StorageIndex> > b_ref(b.const_cast_derived());
|
||||||
cholmod_sparse b_cs = viewAsCholmod(b_ref);
|
cholmod_sparse b_cs = viewAsCholmod(b_ref);
|
||||||
cholmod_sparse* x_cs = internal::cm_spsolve<StorageIndex>(CHOLMOD_A, *m_cholmodFactor, b_cs, m_cholmod);
|
cholmod_sparse* x_cs = cholmod_spsolve(CHOLMOD_A, m_cholmodFactor, &b_cs, &m_cholmod);
|
||||||
if(!x_cs)
|
if(!x_cs)
|
||||||
{
|
{
|
||||||
this->m_info = NumericalIssue;
|
this->m_info = NumericalIssue;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO optimize this copy by swapping when possible (be careful with alignment, etc.)
|
// TODO optimize this copy by swapping when possible (be careful with alignment, etc.)
|
||||||
// NOTE cholmod_spsolve in fact just calls the dense solver for blocks of 4 columns at a time (similar to Eigen's sparse solver)
|
|
||||||
dest.derived() = viewAsEigen<typename DestDerived::Scalar,ColMajor,typename DestDerived::StorageIndex>(*x_cs);
|
dest.derived() = viewAsEigen<typename DestDerived::Scalar,ColMajor,typename DestDerived::StorageIndex>(*x_cs);
|
||||||
internal::cm_free_sparse<StorageIndex>(x_cs, m_cholmod);
|
cholmod_free_sparse(&x_cs, &m_cholmod);
|
||||||
}
|
}
|
||||||
#endif // EIGEN_PARSED_BY_DOXYGEN
|
#endif // EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
|
||||||
|
|||||||
@@ -1,406 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2017 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_ARITHMETIC_SEQUENCE_H
|
|
||||||
#define EIGEN_ARITHMETIC_SEQUENCE_H
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
#if (!EIGEN_HAS_CXX11) || !((!EIGEN_COMP_GNUC) || EIGEN_COMP_GNUC>=48)
|
|
||||||
template<typename T> struct aseq_negate {};
|
|
||||||
|
|
||||||
template<> struct aseq_negate<Index> {
|
|
||||||
typedef Index type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<int N> struct aseq_negate<FixedInt<N> > {
|
|
||||||
typedef FixedInt<-N> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Compilation error in the following case:
|
|
||||||
template<> struct aseq_negate<FixedInt<DynamicIndex> > {};
|
|
||||||
|
|
||||||
template<typename FirstType,typename SizeType,typename IncrType,
|
|
||||||
bool FirstIsSymbolic=symbolic::is_symbolic<FirstType>::value,
|
|
||||||
bool SizeIsSymbolic =symbolic::is_symbolic<SizeType>::value>
|
|
||||||
struct aseq_reverse_first_type {
|
|
||||||
typedef Index type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename FirstType,typename SizeType,typename IncrType>
|
|
||||||
struct aseq_reverse_first_type<FirstType,SizeType,IncrType,true,true> {
|
|
||||||
typedef symbolic::AddExpr<FirstType,
|
|
||||||
symbolic::ProductExpr<symbolic::AddExpr<SizeType,symbolic::ValueExpr<FixedInt<-1> > >,
|
|
||||||
symbolic::ValueExpr<IncrType> >
|
|
||||||
> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename SizeType,typename IncrType,typename EnableIf = void>
|
|
||||||
struct aseq_reverse_first_type_aux {
|
|
||||||
typedef Index type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename SizeType,typename IncrType>
|
|
||||||
struct aseq_reverse_first_type_aux<SizeType,IncrType,typename internal::enable_if<bool((SizeType::value+IncrType::value)|0x1)>::type> {
|
|
||||||
typedef FixedInt<(SizeType::value-1)*IncrType::value> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename FirstType,typename SizeType,typename IncrType>
|
|
||||||
struct aseq_reverse_first_type<FirstType,SizeType,IncrType,true,false> {
|
|
||||||
typedef typename aseq_reverse_first_type_aux<SizeType,IncrType>::type Aux;
|
|
||||||
typedef symbolic::AddExpr<FirstType,symbolic::ValueExpr<Aux> > type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename FirstType,typename SizeType,typename IncrType>
|
|
||||||
struct aseq_reverse_first_type<FirstType,SizeType,IncrType,false,true> {
|
|
||||||
typedef symbolic::AddExpr<symbolic::ProductExpr<symbolic::AddExpr<SizeType,symbolic::ValueExpr<FixedInt<-1> > >,
|
|
||||||
symbolic::ValueExpr<IncrType> >,
|
|
||||||
symbolic::ValueExpr<> > type;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Helper to cleanup the type of the increment:
|
|
||||||
template<typename T> struct cleanup_seq_incr {
|
|
||||||
typedef typename cleanup_index_type<T,DynamicIndex>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
|
||||||
// seq(first,last,incr) and seqN(first,size,incr)
|
|
||||||
//--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template<typename FirstType=Index,typename SizeType=Index,typename IncrType=internal::FixedInt<1> >
|
|
||||||
class ArithmeticSequence;
|
|
||||||
|
|
||||||
template<typename FirstType,typename SizeType,typename IncrType>
|
|
||||||
ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,
|
|
||||||
typename internal::cleanup_index_type<SizeType>::type,
|
|
||||||
typename internal::cleanup_seq_incr<IncrType>::type >
|
|
||||||
seqN(FirstType first, SizeType size, IncrType incr);
|
|
||||||
|
|
||||||
/** \class ArithmeticSequence
|
|
||||||
* \ingroup Core_Module
|
|
||||||
*
|
|
||||||
* This class represents an arithmetic progression \f$ a_0, a_1, a_2, ..., a_{n-1}\f$ defined by
|
|
||||||
* its \em first value \f$ a_0 \f$, its \em size (aka length) \em n, and the \em increment (aka stride)
|
|
||||||
* that is equal to \f$ a_{i+1}-a_{i}\f$ for any \em i.
|
|
||||||
*
|
|
||||||
* It is internally used as the return type of the Eigen::seq and Eigen::seqN functions, and as the input arguments
|
|
||||||
* of DenseBase::operator()(const RowIndices&, const ColIndices&), and most of the time this is the
|
|
||||||
* only way it is used.
|
|
||||||
*
|
|
||||||
* \tparam FirstType type of the first element, usually an Index,
|
|
||||||
* but internally it can be a symbolic expression
|
|
||||||
* \tparam SizeType type representing the size of the sequence, usually an Index
|
|
||||||
* or a compile time integral constant. Internally, it can also be a symbolic expression
|
|
||||||
* \tparam IncrType type of the increment, can be a runtime Index, or a compile time integral constant (default is compile-time 1)
|
|
||||||
*
|
|
||||||
* \sa Eigen::seq, Eigen::seqN, DenseBase::operator()(const RowIndices&, const ColIndices&), class IndexedView
|
|
||||||
*/
|
|
||||||
template<typename FirstType,typename SizeType,typename IncrType>
|
|
||||||
class ArithmeticSequence
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ArithmeticSequence(FirstType first, SizeType size) : m_first(first), m_size(size) {}
|
|
||||||
ArithmeticSequence(FirstType first, SizeType size, IncrType incr) : m_first(first), m_size(size), m_incr(incr) {}
|
|
||||||
|
|
||||||
enum {
|
|
||||||
SizeAtCompileTime = internal::get_fixed_value<SizeType>::value,
|
|
||||||
IncrAtCompileTime = internal::get_fixed_value<IncrType,DynamicIndex>::value
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \returns the size, i.e., number of elements, of the sequence */
|
|
||||||
Index size() const { return m_size; }
|
|
||||||
|
|
||||||
/** \returns the first element \f$ a_0 \f$ in the sequence */
|
|
||||||
Index first() const { return m_first; }
|
|
||||||
|
|
||||||
/** \returns the value \f$ a_i \f$ at index \a i in the sequence. */
|
|
||||||
Index operator[](Index i) const { return m_first + i * m_incr; }
|
|
||||||
|
|
||||||
const FirstType& firstObject() const { return m_first; }
|
|
||||||
const SizeType& sizeObject() const { return m_size; }
|
|
||||||
const IncrType& incrObject() const { return m_incr; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
FirstType m_first;
|
|
||||||
SizeType m_size;
|
|
||||||
IncrType m_incr;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
#if EIGEN_HAS_CXX11 && ((!EIGEN_COMP_GNUC) || EIGEN_COMP_GNUC>=48)
|
|
||||||
auto reverse() const -> decltype(Eigen::seqN(m_first+(m_size+fix<-1>())*m_incr,m_size,-m_incr)) {
|
|
||||||
return seqN(m_first+(m_size+fix<-1>())*m_incr,m_size,-m_incr);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
protected:
|
|
||||||
typedef typename internal::aseq_negate<IncrType>::type ReverseIncrType;
|
|
||||||
typedef typename internal::aseq_reverse_first_type<FirstType,SizeType,IncrType>::type ReverseFirstType;
|
|
||||||
public:
|
|
||||||
ArithmeticSequence<ReverseFirstType,SizeType,ReverseIncrType>
|
|
||||||
reverse() const {
|
|
||||||
return seqN(m_first+(m_size+fix<-1>())*m_incr,m_size,-m_incr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \returns an ArithmeticSequence starting at \a first, of length \a size, and increment \a incr
|
|
||||||
*
|
|
||||||
* \sa seqN(FirstType,SizeType), seq(FirstType,LastType,IncrType) */
|
|
||||||
template<typename FirstType,typename SizeType,typename IncrType>
|
|
||||||
ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,typename internal::cleanup_index_type<SizeType>::type,typename internal::cleanup_seq_incr<IncrType>::type >
|
|
||||||
seqN(FirstType first, SizeType size, IncrType incr) {
|
|
||||||
return ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,typename internal::cleanup_index_type<SizeType>::type,typename internal::cleanup_seq_incr<IncrType>::type>(first,size,incr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \returns an ArithmeticSequence starting at \a first, of length \a size, and unit increment
|
|
||||||
*
|
|
||||||
* \sa seqN(FirstType,SizeType,IncrType), seq(FirstType,LastType) */
|
|
||||||
template<typename FirstType,typename SizeType>
|
|
||||||
ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,typename internal::cleanup_index_type<SizeType>::type >
|
|
||||||
seqN(FirstType first, SizeType size) {
|
|
||||||
return ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,typename internal::cleanup_index_type<SizeType>::type>(first,size);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if EIGEN_HAS_CXX11
|
|
||||||
|
|
||||||
/** \returns an ArithmeticSequence starting at \a f, up (or down) to \a l, and with positive (or negative) increment \a incr
|
|
||||||
*
|
|
||||||
* It is essentially an alias to:
|
|
||||||
* \code
|
|
||||||
* seqN(f, (l-f+incr)/incr, incr);
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* \sa seqN(FirstType,SizeType,IncrType), seq(FirstType,LastType)
|
|
||||||
*/
|
|
||||||
template<typename FirstType,typename LastType>
|
|
||||||
auto seq(FirstType f, LastType l) -> decltype(seqN(typename internal::cleanup_index_type<FirstType>::type(f),
|
|
||||||
( typename internal::cleanup_index_type<LastType>::type(l)
|
|
||||||
- typename internal::cleanup_index_type<FirstType>::type(f)+fix<1>())))
|
|
||||||
{
|
|
||||||
return seqN(typename internal::cleanup_index_type<FirstType>::type(f),
|
|
||||||
(typename internal::cleanup_index_type<LastType>::type(l)
|
|
||||||
-typename internal::cleanup_index_type<FirstType>::type(f)+fix<1>()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \returns an ArithmeticSequence starting at \a f, up (or down) to \a l, and unit increment
|
|
||||||
*
|
|
||||||
* It is essentially an alias to:
|
|
||||||
* \code
|
|
||||||
* seqN(f,l-f+1);
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* \sa seqN(FirstType,SizeType), seq(FirstType,LastType,IncrType)
|
|
||||||
*/
|
|
||||||
template<typename FirstType,typename LastType, typename IncrType>
|
|
||||||
auto seq(FirstType f, LastType l, IncrType incr)
|
|
||||||
-> decltype(seqN(typename internal::cleanup_index_type<FirstType>::type(f),
|
|
||||||
( typename internal::cleanup_index_type<LastType>::type(l)
|
|
||||||
- typename internal::cleanup_index_type<FirstType>::type(f)+typename internal::cleanup_seq_incr<IncrType>::type(incr)
|
|
||||||
) / typename internal::cleanup_seq_incr<IncrType>::type(incr),
|
|
||||||
typename internal::cleanup_seq_incr<IncrType>::type(incr)))
|
|
||||||
{
|
|
||||||
typedef typename internal::cleanup_seq_incr<IncrType>::type CleanedIncrType;
|
|
||||||
return seqN(typename internal::cleanup_index_type<FirstType>::type(f),
|
|
||||||
( typename internal::cleanup_index_type<LastType>::type(l)
|
|
||||||
-typename internal::cleanup_index_type<FirstType>::type(f)+CleanedIncrType(incr)) / CleanedIncrType(incr),
|
|
||||||
CleanedIncrType(incr));
|
|
||||||
}
|
|
||||||
|
|
||||||
#else // EIGEN_HAS_CXX11
|
|
||||||
|
|
||||||
template<typename FirstType,typename LastType>
|
|
||||||
typename internal::enable_if<!(symbolic::is_symbolic<FirstType>::value || symbolic::is_symbolic<LastType>::value),
|
|
||||||
ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,Index> >::type
|
|
||||||
seq(FirstType f, LastType l)
|
|
||||||
{
|
|
||||||
return seqN(typename internal::cleanup_index_type<FirstType>::type(f),
|
|
||||||
Index((typename internal::cleanup_index_type<LastType>::type(l)-typename internal::cleanup_index_type<FirstType>::type(f)+fix<1>())));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename FirstTypeDerived,typename LastType>
|
|
||||||
typename internal::enable_if<!symbolic::is_symbolic<LastType>::value,
|
|
||||||
ArithmeticSequence<FirstTypeDerived, symbolic::AddExpr<symbolic::AddExpr<symbolic::NegateExpr<FirstTypeDerived>,symbolic::ValueExpr<> >,
|
|
||||||
symbolic::ValueExpr<internal::FixedInt<1> > > > >::type
|
|
||||||
seq(const symbolic::BaseExpr<FirstTypeDerived> &f, LastType l)
|
|
||||||
{
|
|
||||||
return seqN(f.derived(),(typename internal::cleanup_index_type<LastType>::type(l)-f.derived()+fix<1>()));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename FirstType,typename LastTypeDerived>
|
|
||||||
typename internal::enable_if<!symbolic::is_symbolic<FirstType>::value,
|
|
||||||
ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,
|
|
||||||
symbolic::AddExpr<symbolic::AddExpr<LastTypeDerived,symbolic::ValueExpr<> >,
|
|
||||||
symbolic::ValueExpr<internal::FixedInt<1> > > > >::type
|
|
||||||
seq(FirstType f, const symbolic::BaseExpr<LastTypeDerived> &l)
|
|
||||||
{
|
|
||||||
return seqN(typename internal::cleanup_index_type<FirstType>::type(f),(l.derived()-typename internal::cleanup_index_type<FirstType>::type(f)+fix<1>()));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename FirstTypeDerived,typename LastTypeDerived>
|
|
||||||
ArithmeticSequence<FirstTypeDerived,
|
|
||||||
symbolic::AddExpr<symbolic::AddExpr<LastTypeDerived,symbolic::NegateExpr<FirstTypeDerived> >,symbolic::ValueExpr<internal::FixedInt<1> > > >
|
|
||||||
seq(const symbolic::BaseExpr<FirstTypeDerived> &f, const symbolic::BaseExpr<LastTypeDerived> &l)
|
|
||||||
{
|
|
||||||
return seqN(f.derived(),(l.derived()-f.derived()+fix<1>()));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename FirstType,typename LastType, typename IncrType>
|
|
||||||
typename internal::enable_if<!(symbolic::is_symbolic<FirstType>::value || symbolic::is_symbolic<LastType>::value),
|
|
||||||
ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,Index,typename internal::cleanup_seq_incr<IncrType>::type> >::type
|
|
||||||
seq(FirstType f, LastType l, IncrType incr)
|
|
||||||
{
|
|
||||||
typedef typename internal::cleanup_seq_incr<IncrType>::type CleanedIncrType;
|
|
||||||
return seqN(typename internal::cleanup_index_type<FirstType>::type(f),
|
|
||||||
Index((typename internal::cleanup_index_type<LastType>::type(l)-typename internal::cleanup_index_type<FirstType>::type(f)+CleanedIncrType(incr))/CleanedIncrType(incr)), incr);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename FirstTypeDerived,typename LastType, typename IncrType>
|
|
||||||
typename internal::enable_if<!symbolic::is_symbolic<LastType>::value,
|
|
||||||
ArithmeticSequence<FirstTypeDerived,
|
|
||||||
symbolic::QuotientExpr<symbolic::AddExpr<symbolic::AddExpr<symbolic::NegateExpr<FirstTypeDerived>,
|
|
||||||
symbolic::ValueExpr<> >,
|
|
||||||
symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
|
|
||||||
symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
|
|
||||||
typename internal::cleanup_seq_incr<IncrType>::type> >::type
|
|
||||||
seq(const symbolic::BaseExpr<FirstTypeDerived> &f, LastType l, IncrType incr)
|
|
||||||
{
|
|
||||||
typedef typename internal::cleanup_seq_incr<IncrType>::type CleanedIncrType;
|
|
||||||
return seqN(f.derived(),(typename internal::cleanup_index_type<LastType>::type(l)-f.derived()+CleanedIncrType(incr))/CleanedIncrType(incr), incr);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename FirstType,typename LastTypeDerived, typename IncrType>
|
|
||||||
typename internal::enable_if<!symbolic::is_symbolic<FirstType>::value,
|
|
||||||
ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,
|
|
||||||
symbolic::QuotientExpr<symbolic::AddExpr<symbolic::AddExpr<LastTypeDerived,symbolic::ValueExpr<> >,
|
|
||||||
symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
|
|
||||||
symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
|
|
||||||
typename internal::cleanup_seq_incr<IncrType>::type> >::type
|
|
||||||
seq(FirstType f, const symbolic::BaseExpr<LastTypeDerived> &l, IncrType incr)
|
|
||||||
{
|
|
||||||
typedef typename internal::cleanup_seq_incr<IncrType>::type CleanedIncrType;
|
|
||||||
return seqN(typename internal::cleanup_index_type<FirstType>::type(f),
|
|
||||||
(l.derived()-typename internal::cleanup_index_type<FirstType>::type(f)+CleanedIncrType(incr))/CleanedIncrType(incr), incr);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename FirstTypeDerived,typename LastTypeDerived, typename IncrType>
|
|
||||||
ArithmeticSequence<FirstTypeDerived,
|
|
||||||
symbolic::QuotientExpr<symbolic::AddExpr<symbolic::AddExpr<LastTypeDerived,
|
|
||||||
symbolic::NegateExpr<FirstTypeDerived> >,
|
|
||||||
symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
|
|
||||||
symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
|
|
||||||
typename internal::cleanup_seq_incr<IncrType>::type>
|
|
||||||
seq(const symbolic::BaseExpr<FirstTypeDerived> &f, const symbolic::BaseExpr<LastTypeDerived> &l, IncrType incr)
|
|
||||||
{
|
|
||||||
typedef typename internal::cleanup_seq_incr<IncrType>::type CleanedIncrType;
|
|
||||||
return seqN(f.derived(),(l.derived()-f.derived()+CleanedIncrType(incr))/CleanedIncrType(incr), incr);
|
|
||||||
}
|
|
||||||
#endif // EIGEN_HAS_CXX11
|
|
||||||
|
|
||||||
#if EIGEN_HAS_CXX11
|
|
||||||
/** \cpp11
|
|
||||||
* \returns a symbolic ArithmeticSequence representing the last \a size elements with a unit increment.
|
|
||||||
*
|
|
||||||
* \anchor indexing_lastN
|
|
||||||
*
|
|
||||||
* It is a shortcut for: \code seq(last+fix<1>-size, last) \endcode
|
|
||||||
*
|
|
||||||
* \sa lastN(SizeType,IncrType, seqN(FirstType,SizeType), seq(FirstType,LastType) */
|
|
||||||
template<typename SizeType>
|
|
||||||
auto lastN(SizeType size)
|
|
||||||
-> decltype(seqN(Eigen::last+fix<1>()-size, size))
|
|
||||||
{
|
|
||||||
return seqN(Eigen::last+fix<1>()-size, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \cpp11
|
|
||||||
* \returns a symbolic ArithmeticSequence representing the last \a size elements with increment \a incr.
|
|
||||||
*
|
|
||||||
* \anchor indexing_lastN_with_incr
|
|
||||||
*
|
|
||||||
* It is a shortcut for: \code seqN(last-(size-fix<1>)*incr, size, incr) \endcode
|
|
||||||
*
|
|
||||||
* \sa lastN(SizeType), seqN(FirstType,SizeType), seq(FirstType,LastType,IncrType) */
|
|
||||||
template<typename SizeType,typename IncrType>
|
|
||||||
auto lastN(SizeType size, IncrType incr)
|
|
||||||
-> decltype(seqN(Eigen::last-(size-fix<1>())*incr, size, incr))
|
|
||||||
{
|
|
||||||
return seqN(Eigen::last-(size-fix<1>())*incr, size, incr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
// Convert a symbolic span into a usable one (i.e., remove last/end "keywords")
|
|
||||||
template<typename T>
|
|
||||||
struct make_size_type {
|
|
||||||
typedef typename internal::conditional<symbolic::is_symbolic<T>::value, Index, T>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename FirstType,typename SizeType,typename IncrType,int XprSize>
|
|
||||||
struct IndexedViewCompatibleType<ArithmeticSequence<FirstType,SizeType,IncrType>, XprSize> {
|
|
||||||
typedef ArithmeticSequence<Index,typename make_size_type<SizeType>::type,IncrType> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename FirstType,typename SizeType,typename IncrType>
|
|
||||||
ArithmeticSequence<Index,typename make_size_type<SizeType>::type,IncrType>
|
|
||||||
makeIndexedViewCompatible(const ArithmeticSequence<FirstType,SizeType,IncrType>& ids, Index size,SpecializedType) {
|
|
||||||
return ArithmeticSequence<Index,typename make_size_type<SizeType>::type,IncrType>(
|
|
||||||
eval_expr_given_size(ids.firstObject(),size),eval_expr_given_size(ids.sizeObject(),size),ids.incrObject());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename FirstType,typename SizeType,typename IncrType>
|
|
||||||
struct get_compile_time_incr<ArithmeticSequence<FirstType,SizeType,IncrType> > {
|
|
||||||
enum { value = get_fixed_value<IncrType,DynamicIndex>::value };
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
|
|
||||||
/** \namespace Eigen::indexing
|
|
||||||
* \ingroup Core_Module
|
|
||||||
*
|
|
||||||
* The sole purpose of this namespace is to be able to import all functions
|
|
||||||
* and symbols that are expected to be used within operator() for indexing
|
|
||||||
* and slicing. If you already imported the whole Eigen namespace:
|
|
||||||
* \code using namespace Eigen; \endcode
|
|
||||||
* then you are already all set. Otherwise, if you don't want/cannot import
|
|
||||||
* the whole Eigen namespace, the following line:
|
|
||||||
* \code using namespace Eigen::indexing; \endcode
|
|
||||||
* is equivalent to:
|
|
||||||
* \code
|
|
||||||
using Eigen::all;
|
|
||||||
using Eigen::seq;
|
|
||||||
using Eigen::seqN;
|
|
||||||
using Eigen::lastN; // c++11 only
|
|
||||||
using Eigen::last;
|
|
||||||
using Eigen::lastp1;
|
|
||||||
using Eigen::fix;
|
|
||||||
\endcode
|
|
||||||
*/
|
|
||||||
namespace indexing {
|
|
||||||
using Eigen::all;
|
|
||||||
using Eigen::seq;
|
|
||||||
using Eigen::seqN;
|
|
||||||
#if EIGEN_HAS_CXX11
|
|
||||||
using Eigen::lastN;
|
|
||||||
#endif
|
|
||||||
using Eigen::last;
|
|
||||||
using Eigen::lastp1;
|
|
||||||
using Eigen::fix;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_ARITHMETIC_SEQUENCE_H
|
|
||||||
@@ -157,58 +157,11 @@ class Array
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
Array& operator=(Array&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_assignable<Scalar>::value)
|
Array& operator=(Array&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_assignable<Scalar>::value)
|
||||||
{
|
{
|
||||||
Base::operator=(std::move(other));
|
other.swap(*this);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if EIGEN_HAS_CXX11
|
|
||||||
/** \brief Construct a row of column vector with fixed size from an arbitrary number of coefficients. \cpp11
|
|
||||||
*
|
|
||||||
* \only_for_vectors
|
|
||||||
*
|
|
||||||
* This constructor is for 1D array or vectors with more than 4 coefficients.
|
|
||||||
* There exists C++98 analogue constructors for fixed-size array/vector having 1, 2, 3, or 4 coefficients.
|
|
||||||
*
|
|
||||||
* \warning To construct a column (resp. row) vector of fixed length, the number of values passed to this
|
|
||||||
* constructor must match the the fixed number of rows (resp. columns) of \c *this.
|
|
||||||
*
|
|
||||||
* Example: \include Array_variadic_ctor_cxx11.cpp
|
|
||||||
* Output: \verbinclude Array_variadic_ctor_cxx11.out
|
|
||||||
*
|
|
||||||
* \sa Array(const std::initializer_list<std::initializer_list<Scalar>>&)
|
|
||||||
* \sa Array(const Scalar&), Array(const Scalar&,const Scalar&)
|
|
||||||
*/
|
|
||||||
template <typename... ArgTypes>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args)
|
|
||||||
: Base(a0, a1, a2, a3, args...) {}
|
|
||||||
|
|
||||||
/** \brief Constructs an array and initializes it from the coefficients given as initializer-lists grouped by row. \cpp11
|
|
||||||
*
|
|
||||||
* In the general case, the constructor takes a list of rows, each row being represented as a list of coefficients:
|
|
||||||
*
|
|
||||||
* Example: \include Array_initializer_list_23_cxx11.cpp
|
|
||||||
* Output: \verbinclude Array_initializer_list_23_cxx11.out
|
|
||||||
*
|
|
||||||
* Each of the inner initializer lists must contain the exact same number of elements, otherwise an assertion is triggered.
|
|
||||||
*
|
|
||||||
* In the case of a compile-time column 1D array, implicit transposition from a single row is allowed.
|
|
||||||
* Therefore <code> Array<int,Dynamic,1>{{1,2,3,4,5}}</code> is legal and the more verbose syntax
|
|
||||||
* <code>Array<int,Dynamic,1>{{1},{2},{3},{4},{5}}</code> can be avoided:
|
|
||||||
*
|
|
||||||
* Example: \include Array_initializer_list_vector_cxx11.cpp
|
|
||||||
* Output: \verbinclude Array_initializer_list_vector_cxx11.out
|
|
||||||
*
|
|
||||||
* In the case of fixed-sized arrays, the initializer list sizes must exactly match the array sizes,
|
|
||||||
* and implicit transposition is allowed for compile-time 1D arrays only.
|
|
||||||
*
|
|
||||||
* \sa Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args)
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE Array(const std::initializer_list<std::initializer_list<Scalar>>& list) : Base(list) {}
|
|
||||||
#endif // end EIGEN_HAS_CXX11
|
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
template<typename T>
|
template<typename T>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
@@ -225,7 +178,6 @@ class Array
|
|||||||
Base::_check_template_params();
|
Base::_check_template_params();
|
||||||
this->template _init2<T0,T1>(val0, val1);
|
this->template _init2<T0,T1>(val0, val1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/** \brief Constructs a fixed-sized array initialized with coefficients starting at \a data */
|
/** \brief Constructs a fixed-sized array initialized with coefficients starting at \a data */
|
||||||
EIGEN_DEVICE_FUNC explicit Array(const Scalar *data);
|
EIGEN_DEVICE_FUNC explicit Array(const Scalar *data);
|
||||||
@@ -237,8 +189,7 @@ class Array
|
|||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
EIGEN_STRONG_INLINE explicit Array(Index dim);
|
EIGEN_STRONG_INLINE explicit Array(Index dim);
|
||||||
/** constructs an initialized 1x1 Array with the given coefficient
|
/** constructs an initialized 1x1 Array with the given coefficient */
|
||||||
* \sa const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args */
|
|
||||||
Array(const Scalar& value);
|
Array(const Scalar& value);
|
||||||
/** constructs an uninitialized array with \a rows rows and \a cols columns.
|
/** constructs an uninitialized array with \a rows rows and \a cols columns.
|
||||||
*
|
*
|
||||||
@@ -246,14 +197,11 @@ class Array
|
|||||||
* it is redundant to pass these parameters, so one should use the default constructor
|
* it is redundant to pass these parameters, so one should use the default constructor
|
||||||
* Array() instead. */
|
* Array() instead. */
|
||||||
Array(Index rows, Index cols);
|
Array(Index rows, Index cols);
|
||||||
/** constructs an initialized 2D vector with given coefficients
|
/** constructs an initialized 2D vector with given coefficients */
|
||||||
* \sa Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args) */
|
|
||||||
Array(const Scalar& val0, const Scalar& val1);
|
Array(const Scalar& val0, const Scalar& val1);
|
||||||
#endif // end EIGEN_PARSED_BY_DOXYGEN
|
#endif
|
||||||
|
|
||||||
/** constructs an initialized 3D vector with given coefficients
|
/** constructs an initialized 3D vector with given coefficients */
|
||||||
* \sa Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args)
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2)
|
EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2)
|
||||||
{
|
{
|
||||||
@@ -263,9 +211,7 @@ class Array
|
|||||||
m_storage.data()[1] = val1;
|
m_storage.data()[1] = val1;
|
||||||
m_storage.data()[2] = val2;
|
m_storage.data()[2] = val2;
|
||||||
}
|
}
|
||||||
/** constructs an initialized 4D vector with given coefficients
|
/** constructs an initialized 4D vector with given coefficients */
|
||||||
* \sa Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args)
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2, const Scalar& val3)
|
EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2, const Scalar& val3)
|
||||||
{
|
{
|
||||||
@@ -296,10 +242,8 @@ class Array
|
|||||||
: Base(other.derived())
|
: Base(other.derived())
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC inline Index innerStride() const { return 1; }
|
||||||
inline Index innerStride() const EIGEN_NOEXCEPT{ return 1; }
|
EIGEN_DEVICE_FUNC inline Index outerStride() const { return this->innerSize(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
|
||||||
inline Index outerStride() const EIGEN_NOEXCEPT { return this->innerSize(); }
|
|
||||||
|
|
||||||
#ifdef EIGEN_ARRAY_PLUGIN
|
#ifdef EIGEN_ARRAY_PLUGIN
|
||||||
#include EIGEN_ARRAY_PLUGIN
|
#include EIGEN_ARRAY_PLUGIN
|
||||||
@@ -314,7 +258,7 @@ class Array
|
|||||||
/** \defgroup arraytypedefs Global array typedefs
|
/** \defgroup arraytypedefs Global array typedefs
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
*
|
*
|
||||||
* %Eigen defines several typedef shortcuts for most common 1D and 2D array types.
|
* Eigen defines several typedef shortcuts for most common 1D and 2D array types.
|
||||||
*
|
*
|
||||||
* The general patterns are the following:
|
* The general patterns are the following:
|
||||||
*
|
*
|
||||||
@@ -327,12 +271,6 @@ class Array
|
|||||||
* There are also \c ArraySizeType which are self-explanatory. For example, \c Array4cf is
|
* There are also \c ArraySizeType which are self-explanatory. For example, \c Array4cf is
|
||||||
* a fixed-size 1D array of 4 complex floats.
|
* a fixed-size 1D array of 4 complex floats.
|
||||||
*
|
*
|
||||||
* With \cpp11, template alias are also defined for common sizes.
|
|
||||||
* They follow the same pattern as above except that the scalar type suffix is replaced by a
|
|
||||||
* template parameter, i.e.:
|
|
||||||
* - `ArrayRowsCols<Type>` where `Rows` and `Cols` can be \c 2,\c 3,\c 4, or \c X for fixed or dynamic size.
|
|
||||||
* - `ArraySize<Type>` where `Size` can be \c 2,\c 3,\c 4 or \c X for fixed or dynamic size 1D arrays.
|
|
||||||
*
|
|
||||||
* \sa class Array
|
* \sa class Array
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -365,42 +303,8 @@ EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex<double>, cd)
|
|||||||
|
|
||||||
#undef EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES
|
#undef EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES
|
||||||
#undef EIGEN_MAKE_ARRAY_TYPEDEFS
|
#undef EIGEN_MAKE_ARRAY_TYPEDEFS
|
||||||
#undef EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS
|
|
||||||
|
|
||||||
#if EIGEN_HAS_CXX11
|
#undef EIGEN_MAKE_ARRAY_TYPEDEFS_LARGE
|
||||||
|
|
||||||
#define EIGEN_MAKE_ARRAY_TYPEDEFS(Size, SizeSuffix) \
|
|
||||||
/** \ingroup arraytypedefs */ \
|
|
||||||
/** \brief \cpp11 */ \
|
|
||||||
template <typename Type> \
|
|
||||||
using Array##SizeSuffix##SizeSuffix = Array<Type, Size, Size>; \
|
|
||||||
/** \ingroup arraytypedefs */ \
|
|
||||||
/** \brief \cpp11 */ \
|
|
||||||
template <typename Type> \
|
|
||||||
using Array##SizeSuffix = Array<Type, Size, 1>;
|
|
||||||
|
|
||||||
#define EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Size) \
|
|
||||||
/** \ingroup arraytypedefs */ \
|
|
||||||
/** \brief \cpp11 */ \
|
|
||||||
template <typename Type> \
|
|
||||||
using Array##Size##X = Array<Type, Size, Dynamic>; \
|
|
||||||
/** \ingroup arraytypedefs */ \
|
|
||||||
/** \brief \cpp11 */ \
|
|
||||||
template <typename Type> \
|
|
||||||
using Array##X##Size = Array<Type, Dynamic, Size>;
|
|
||||||
|
|
||||||
EIGEN_MAKE_ARRAY_TYPEDEFS(2, 2)
|
|
||||||
EIGEN_MAKE_ARRAY_TYPEDEFS(3, 3)
|
|
||||||
EIGEN_MAKE_ARRAY_TYPEDEFS(4, 4)
|
|
||||||
EIGEN_MAKE_ARRAY_TYPEDEFS(Dynamic, X)
|
|
||||||
EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(2)
|
|
||||||
EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(3)
|
|
||||||
EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(4)
|
|
||||||
|
|
||||||
#undef EIGEN_MAKE_ARRAY_TYPEDEFS
|
|
||||||
#undef EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS
|
|
||||||
|
|
||||||
#endif // EIGEN_HAS_CXX11
|
|
||||||
|
|
||||||
#define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \
|
#define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \
|
||||||
using Eigen::Matrix##SizeSuffix##TypeSuffix; \
|
using Eigen::Matrix##SizeSuffix##TypeSuffix; \
|
||||||
|
|||||||
@@ -69,7 +69,6 @@ template<typename Derived> class ArrayBase
|
|||||||
using Base::coeff;
|
using Base::coeff;
|
||||||
using Base::coeffRef;
|
using Base::coeffRef;
|
||||||
using Base::lazyAssign;
|
using Base::lazyAssign;
|
||||||
using Base::operator-;
|
|
||||||
using Base::operator=;
|
using Base::operator=;
|
||||||
using Base::operator+=;
|
using Base::operator+=;
|
||||||
using Base::operator-=;
|
using Base::operator-=;
|
||||||
@@ -89,6 +88,7 @@ template<typename Derived> class ArrayBase
|
|||||||
|
|
||||||
#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::ArrayBase
|
#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::ArrayBase
|
||||||
#define EIGEN_DOC_UNARY_ADDONS(X,Y)
|
#define EIGEN_DOC_UNARY_ADDONS(X,Y)
|
||||||
|
# include "../plugins/CommonCwiseUnaryOps.h"
|
||||||
# include "../plugins/MatrixCwiseUnaryOps.h"
|
# include "../plugins/MatrixCwiseUnaryOps.h"
|
||||||
# include "../plugins/ArrayCwiseUnaryOps.h"
|
# include "../plugins/ArrayCwiseUnaryOps.h"
|
||||||
# include "../plugins/CommonCwiseBinaryOps.h"
|
# include "../plugins/CommonCwiseBinaryOps.h"
|
||||||
|
|||||||
@@ -60,14 +60,14 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
explicit EIGEN_STRONG_INLINE ArrayWrapper(ExpressionType& matrix) : m_expression(matrix) {}
|
explicit EIGEN_STRONG_INLINE ArrayWrapper(ExpressionType& matrix) : m_expression(matrix) {}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index rows() const EIGEN_NOEXCEPT { return m_expression.rows(); }
|
inline Index rows() const { return m_expression.rows(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index cols() const EIGEN_NOEXCEPT { return m_expression.cols(); }
|
inline Index cols() const { return m_expression.cols(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index outerStride() const EIGEN_NOEXCEPT { return m_expression.outerStride(); }
|
inline Index outerStride() const { return m_expression.outerStride(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index innerStride() const EIGEN_NOEXCEPT { return m_expression.innerStride(); }
|
inline Index innerStride() const { return m_expression.innerStride(); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
|
inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
|
||||||
@@ -90,8 +90,8 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline void evalTo(Dest& dst) const { dst = m_expression; }
|
inline void evalTo(Dest& dst) const { dst = m_expression; }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
const typename internal::remove_all<NestedExpressionType>::type&
|
const typename internal::remove_all<NestedExpressionType>::type&
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
nestedExpression() const
|
nestedExpression() const
|
||||||
{
|
{
|
||||||
return m_expression;
|
return m_expression;
|
||||||
@@ -158,14 +158,14 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
explicit inline MatrixWrapper(ExpressionType& matrix) : m_expression(matrix) {}
|
explicit inline MatrixWrapper(ExpressionType& matrix) : m_expression(matrix) {}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index rows() const EIGEN_NOEXCEPT { return m_expression.rows(); }
|
inline Index rows() const { return m_expression.rows(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index cols() const EIGEN_NOEXCEPT { return m_expression.cols(); }
|
inline Index cols() const { return m_expression.cols(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index outerStride() const EIGEN_NOEXCEPT { return m_expression.outerStride(); }
|
inline Index outerStride() const { return m_expression.outerStride(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index innerStride() const EIGEN_NOEXCEPT { return m_expression.innerStride(); }
|
inline Index innerStride() const { return m_expression.innerStride(); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
|
inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace internal {
|
|||||||
|
|
||||||
// copy_using_evaluator_traits is based on assign_traits
|
// copy_using_evaluator_traits is based on assign_traits
|
||||||
|
|
||||||
template <typename DstEvaluator, typename SrcEvaluator, typename AssignFunc, int MaxPacketSize = -1>
|
template <typename DstEvaluator, typename SrcEvaluator, typename AssignFunc>
|
||||||
struct copy_using_evaluator_traits
|
struct copy_using_evaluator_traits
|
||||||
{
|
{
|
||||||
typedef typename DstEvaluator::XprType Dst;
|
typedef typename DstEvaluator::XprType Dst;
|
||||||
@@ -51,15 +51,13 @@ private:
|
|||||||
InnerMaxSize = int(Dst::IsVectorAtCompileTime) ? int(Dst::MaxSizeAtCompileTime)
|
InnerMaxSize = int(Dst::IsVectorAtCompileTime) ? int(Dst::MaxSizeAtCompileTime)
|
||||||
: int(DstFlags)&RowMajorBit ? int(Dst::MaxColsAtCompileTime)
|
: int(DstFlags)&RowMajorBit ? int(Dst::MaxColsAtCompileTime)
|
||||||
: int(Dst::MaxRowsAtCompileTime),
|
: int(Dst::MaxRowsAtCompileTime),
|
||||||
RestrictedInnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(InnerSize,MaxPacketSize),
|
|
||||||
RestrictedLinearSize = EIGEN_SIZE_MIN_PREFER_FIXED(Dst::SizeAtCompileTime,MaxPacketSize),
|
|
||||||
OuterStride = int(outer_stride_at_compile_time<Dst>::ret),
|
OuterStride = int(outer_stride_at_compile_time<Dst>::ret),
|
||||||
MaxSizeAtCompileTime = Dst::SizeAtCompileTime
|
MaxSizeAtCompileTime = Dst::SizeAtCompileTime
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO distinguish between linear traversal and inner-traversals
|
// TODO distinguish between linear traversal and inner-traversals
|
||||||
typedef typename find_best_packet<DstScalar,RestrictedLinearSize>::type LinearPacketType;
|
typedef typename find_best_packet<DstScalar,Dst::SizeAtCompileTime>::type LinearPacketType;
|
||||||
typedef typename find_best_packet<DstScalar,RestrictedInnerSize>::type InnerPacketType;
|
typedef typename find_best_packet<DstScalar,InnerSize>::type InnerPacketType;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
LinearPacketSize = unpacket_traits<LinearPacketType>::size,
|
LinearPacketSize = unpacket_traits<LinearPacketType>::size,
|
||||||
@@ -99,8 +97,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
Traversal = int(Dst::SizeAtCompileTime) == 0 ? int(AllAtOnceTraversal) // If compile-size is zero, traversing will fail at compile-time.
|
Traversal = int(MayLinearVectorize) && (LinearPacketSize>InnerPacketSize) ? int(LinearVectorizedTraversal)
|
||||||
: (int(MayLinearVectorize) && (LinearPacketSize>InnerPacketSize)) ? int(LinearVectorizedTraversal)
|
|
||||||
: int(MayInnerVectorize) ? int(InnerVectorizedTraversal)
|
: int(MayInnerVectorize) ? int(InnerVectorizedTraversal)
|
||||||
: int(MayLinearVectorize) ? int(LinearVectorizedTraversal)
|
: int(MayLinearVectorize) ? int(LinearVectorizedTraversal)
|
||||||
: int(MaySliceVectorize) ? int(SliceVectorizedTraversal)
|
: int(MaySliceVectorize) ? int(SliceVectorizedTraversal)
|
||||||
@@ -175,8 +172,6 @@ public:
|
|||||||
EIGEN_DEBUG_VAR(MaySliceVectorize)
|
EIGEN_DEBUG_VAR(MaySliceVectorize)
|
||||||
std::cerr << "Traversal" << " = " << Traversal << " (" << demangle_traversal(Traversal) << ")" << std::endl;
|
std::cerr << "Traversal" << " = " << Traversal << " (" << demangle_traversal(Traversal) << ")" << std::endl;
|
||||||
EIGEN_DEBUG_VAR(SrcEvaluator::CoeffReadCost)
|
EIGEN_DEBUG_VAR(SrcEvaluator::CoeffReadCost)
|
||||||
EIGEN_DEBUG_VAR(DstEvaluator::CoeffReadCost)
|
|
||||||
EIGEN_DEBUG_VAR(Dst::SizeAtCompileTime)
|
|
||||||
EIGEN_DEBUG_VAR(UnrollingLimit)
|
EIGEN_DEBUG_VAR(UnrollingLimit)
|
||||||
EIGEN_DEBUG_VAR(MayUnrollCompletely)
|
EIGEN_DEBUG_VAR(MayUnrollCompletely)
|
||||||
EIGEN_DEBUG_VAR(MayUnrollInner)
|
EIGEN_DEBUG_VAR(MayUnrollInner)
|
||||||
@@ -317,22 +312,6 @@ template<typename Kernel,
|
|||||||
int Unrolling = Kernel::AssignmentTraits::Unrolling>
|
int Unrolling = Kernel::AssignmentTraits::Unrolling>
|
||||||
struct dense_assignment_loop;
|
struct dense_assignment_loop;
|
||||||
|
|
||||||
/************************
|
|
||||||
***** Special Cases *****
|
|
||||||
************************/
|
|
||||||
|
|
||||||
// Zero-sized assignment is a no-op.
|
|
||||||
template<typename Kernel, int Unrolling>
|
|
||||||
struct dense_assignment_loop<Kernel, AllAtOnceTraversal, Unrolling>
|
|
||||||
{
|
|
||||||
EIGEN_DEVICE_FUNC static void EIGEN_STRONG_INLINE run(Kernel& /*kernel*/)
|
|
||||||
{
|
|
||||||
typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
|
|
||||||
EIGEN_STATIC_ASSERT(int(DstXprType::SizeAtCompileTime) == 0,
|
|
||||||
EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/************************
|
/************************
|
||||||
*** Default traversal ***
|
*** Default traversal ***
|
||||||
************************/
|
************************/
|
||||||
@@ -450,7 +429,7 @@ struct dense_assignment_loop<Kernel, LinearVectorizedTraversal, CompleteUnrollin
|
|||||||
|
|
||||||
enum { size = DstXprType::SizeAtCompileTime,
|
enum { size = DstXprType::SizeAtCompileTime,
|
||||||
packetSize =unpacket_traits<PacketType>::size,
|
packetSize =unpacket_traits<PacketType>::size,
|
||||||
alignedSize = (int(size)/packetSize)*packetSize };
|
alignedSize = (size/packetSize)*packetSize };
|
||||||
|
|
||||||
copy_using_evaluator_innervec_CompleteUnrolling<Kernel, 0, alignedSize>::run(kernel);
|
copy_using_evaluator_innervec_CompleteUnrolling<Kernel, 0, alignedSize>::run(kernel);
|
||||||
copy_using_evaluator_DefaultTraversal_CompleteUnrolling<Kernel, alignedSize, size>::run(kernel);
|
copy_using_evaluator_DefaultTraversal_CompleteUnrolling<Kernel, alignedSize, size>::run(kernel);
|
||||||
@@ -551,7 +530,7 @@ struct dense_assignment_loop<Kernel, SliceVectorizedTraversal, NoUnrolling>
|
|||||||
const Scalar *dst_ptr = kernel.dstDataPtr();
|
const Scalar *dst_ptr = kernel.dstDataPtr();
|
||||||
if((!bool(dstIsAligned)) && (UIntPtr(dst_ptr) % sizeof(Scalar))>0)
|
if((!bool(dstIsAligned)) && (UIntPtr(dst_ptr) % sizeof(Scalar))>0)
|
||||||
{
|
{
|
||||||
// the pointer is not aligned-on scalar, so alignment is not possible
|
// the pointer is not aligend-on scalar, so alignment is not possible
|
||||||
return dense_assignment_loop<Kernel,DefaultTraversal,NoUnrolling>::run(kernel);
|
return dense_assignment_loop<Kernel,DefaultTraversal,NoUnrolling>::run(kernel);
|
||||||
}
|
}
|
||||||
const Index packetAlignedMask = packetSize - 1;
|
const Index packetAlignedMask = packetSize - 1;
|
||||||
@@ -589,15 +568,14 @@ struct dense_assignment_loop<Kernel, SliceVectorizedTraversal, InnerUnrolling>
|
|||||||
typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
|
typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
|
||||||
typedef typename Kernel::PacketType PacketType;
|
typedef typename Kernel::PacketType PacketType;
|
||||||
|
|
||||||
enum { innerSize = DstXprType::InnerSizeAtCompileTime,
|
enum { size = DstXprType::InnerSizeAtCompileTime,
|
||||||
packetSize =unpacket_traits<PacketType>::size,
|
packetSize =unpacket_traits<PacketType>::size,
|
||||||
vectorizableSize = (int(innerSize) / int(packetSize)) * int(packetSize),
|
vectorizableSize = (size/packetSize)*packetSize };
|
||||||
size = DstXprType::SizeAtCompileTime };
|
|
||||||
|
|
||||||
for(Index outer = 0; outer < kernel.outerSize(); ++outer)
|
for(Index outer = 0; outer < kernel.outerSize(); ++outer)
|
||||||
{
|
{
|
||||||
copy_using_evaluator_innervec_InnerUnrolling<Kernel, 0, vectorizableSize, 0, 0>::run(kernel, outer);
|
copy_using_evaluator_innervec_InnerUnrolling<Kernel, 0, vectorizableSize, 0, 0>::run(kernel, outer);
|
||||||
copy_using_evaluator_DefaultTraversal_InnerUnrolling<Kernel, vectorizableSize, innerSize>::run(kernel, outer);
|
copy_using_evaluator_DefaultTraversal_InnerUnrolling<Kernel, vectorizableSize, size>::run(kernel, outer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -629,8 +607,7 @@ public:
|
|||||||
typedef typename AssignmentTraits::PacketType PacketType;
|
typedef typename AssignmentTraits::PacketType PacketType;
|
||||||
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC generic_dense_assignment_kernel(DstEvaluatorType &dst, const SrcEvaluatorType &src, const Functor &func, DstXprType& dstExpr)
|
||||||
generic_dense_assignment_kernel(DstEvaluatorType &dst, const SrcEvaluatorType &src, const Functor &func, DstXprType& dstExpr)
|
|
||||||
: m_dst(dst), m_src(src), m_functor(func), m_dstExpr(dstExpr)
|
: m_dst(dst), m_src(src), m_functor(func), m_dstExpr(dstExpr)
|
||||||
{
|
{
|
||||||
#ifdef EIGEN_DEBUG_ASSIGN
|
#ifdef EIGEN_DEBUG_ASSIGN
|
||||||
@@ -638,15 +615,15 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index size() const EIGEN_NOEXCEPT { return m_dstExpr.size(); }
|
EIGEN_DEVICE_FUNC Index size() const { return m_dstExpr.size(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index innerSize() const EIGEN_NOEXCEPT { return m_dstExpr.innerSize(); }
|
EIGEN_DEVICE_FUNC Index innerSize() const { return m_dstExpr.innerSize(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index outerSize() const EIGEN_NOEXCEPT { return m_dstExpr.outerSize(); }
|
EIGEN_DEVICE_FUNC Index outerSize() const { return m_dstExpr.outerSize(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_dstExpr.rows(); }
|
EIGEN_DEVICE_FUNC Index rows() const { return m_dstExpr.rows(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_dstExpr.cols(); }
|
EIGEN_DEVICE_FUNC Index cols() const { return m_dstExpr.cols(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index outerStride() const EIGEN_NOEXCEPT { return m_dstExpr.outerStride(); }
|
EIGEN_DEVICE_FUNC Index outerStride() const { return m_dstExpr.outerStride(); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC DstEvaluatorType& dstEvaluator() EIGEN_NOEXCEPT { return m_dst; }
|
EIGEN_DEVICE_FUNC DstEvaluatorType& dstEvaluator() { return m_dst; }
|
||||||
EIGEN_DEVICE_FUNC const SrcEvaluatorType& srcEvaluator() const EIGEN_NOEXCEPT { return m_src; }
|
EIGEN_DEVICE_FUNC const SrcEvaluatorType& srcEvaluator() const { return m_src; }
|
||||||
|
|
||||||
/// Assign src(row,col) to dst(row,col) through the assignment functor.
|
/// Assign src(row,col) to dst(row,col) through the assignment functor.
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(Index row, Index col)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(Index row, Index col)
|
||||||
@@ -720,27 +697,6 @@ protected:
|
|||||||
DstXprType& m_dstExpr;
|
DstXprType& m_dstExpr;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Special kernel used when computing small products whose operands have dynamic dimensions. It ensures that the
|
|
||||||
// PacketSize used is no larger than 4, thereby increasing the chance that vectorized instructions will be used
|
|
||||||
// when computing the product.
|
|
||||||
|
|
||||||
template<typename DstEvaluatorTypeT, typename SrcEvaluatorTypeT, typename Functor>
|
|
||||||
class restricted_packet_dense_assignment_kernel : public generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, BuiltIn>
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
typedef generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, BuiltIn> Base;
|
|
||||||
public:
|
|
||||||
typedef typename Base::Scalar Scalar;
|
|
||||||
typedef typename Base::DstXprType DstXprType;
|
|
||||||
typedef copy_using_evaluator_traits<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, 4> AssignmentTraits;
|
|
||||||
typedef typename AssignmentTraits::PacketType PacketType;
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC restricted_packet_dense_assignment_kernel(DstEvaluatorTypeT &dst, const SrcEvaluatorTypeT &src, const Functor &func, DstXprType& dstExpr)
|
|
||||||
: Base(dst, src, func, dstExpr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Part 5 : Entry point for dense rectangular assignment
|
* Part 5 : Entry point for dense rectangular assignment
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
@@ -785,16 +741,6 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void call_dense_assignment_loop(DstXprType
|
|||||||
dense_assignment_loop<Kernel>::run(kernel);
|
dense_assignment_loop<Kernel>::run(kernel);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specialization for filling the destination with a constant value.
|
|
||||||
#ifndef EIGEN_GPU_COMPILE_PHASE
|
|
||||||
template<typename DstXprType>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void call_dense_assignment_loop(DstXprType& dst, const Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<typename DstXprType::Scalar>, DstXprType>& src, const internal::assign_op<typename DstXprType::Scalar,typename DstXprType::Scalar>& func)
|
|
||||||
{
|
|
||||||
resize_if_allowed(dst, src, func);
|
|
||||||
std::fill_n(dst.data(), dst.size(), src.functor()());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename DstXprType, typename SrcXprType>
|
template<typename DstXprType, typename SrcXprType>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void call_dense_assignment_loop(DstXprType& dst, const SrcXprType& src)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void call_dense_assignment_loop(DstXprType& dst, const SrcXprType& src)
|
||||||
{
|
{
|
||||||
@@ -810,7 +756,7 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void call_dense_assignment_loop(DstXprType
|
|||||||
// AssignmentKind must define a Kind typedef.
|
// AssignmentKind must define a Kind typedef.
|
||||||
template<typename DstShape, typename SrcShape> struct AssignmentKind;
|
template<typename DstShape, typename SrcShape> struct AssignmentKind;
|
||||||
|
|
||||||
// Assignment kind defined in this file:
|
// Assignement kind defined in this file:
|
||||||
struct Dense2Dense {};
|
struct Dense2Dense {};
|
||||||
struct EigenBase2EigenBase {};
|
struct EigenBase2EigenBase {};
|
||||||
|
|
||||||
@@ -889,27 +835,6 @@ void call_assignment_no_alias(Dst& dst, const Src& src, const Func& func)
|
|||||||
|
|
||||||
Assignment<ActualDstTypeCleaned,Src,Func>::run(actualDst, src, func);
|
Assignment<ActualDstTypeCleaned,Src,Func>::run(actualDst, src, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Dst, typename Src, typename Func>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
void call_restricted_packet_assignment_no_alias(Dst& dst, const Src& src, const Func& func)
|
|
||||||
{
|
|
||||||
typedef evaluator<Dst> DstEvaluatorType;
|
|
||||||
typedef evaluator<Src> SrcEvaluatorType;
|
|
||||||
typedef restricted_packet_dense_assignment_kernel<DstEvaluatorType,SrcEvaluatorType,Func> Kernel;
|
|
||||||
|
|
||||||
EIGEN_STATIC_ASSERT_LVALUE(Dst)
|
|
||||||
EIGEN_CHECK_BINARY_COMPATIBILIY(Func,typename Dst::Scalar,typename Src::Scalar);
|
|
||||||
|
|
||||||
SrcEvaluatorType srcEvaluator(src);
|
|
||||||
resize_if_allowed(dst, src, func);
|
|
||||||
|
|
||||||
DstEvaluatorType dstEvaluator(dst);
|
|
||||||
Kernel kernel(dstEvaluator, srcEvaluator, func, dst.const_cast_derived());
|
|
||||||
|
|
||||||
dense_assignment_loop<Kernel>::run(kernel);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Dst, typename Src>
|
template<typename Dst, typename Src>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
void call_assignment_no_alias(Dst& dst, const Src& src)
|
void call_assignment_no_alias(Dst& dst, const Src& src)
|
||||||
@@ -944,8 +869,7 @@ template<typename Dst, typename Src> void check_for_aliasing(const Dst &dst, con
|
|||||||
template< typename DstXprType, typename SrcXprType, typename Functor, typename Weak>
|
template< typename DstXprType, typename SrcXprType, typename Functor, typename Weak>
|
||||||
struct Assignment<DstXprType, SrcXprType, Functor, Dense2Dense, Weak>
|
struct Assignment<DstXprType, SrcXprType, Functor, Dense2Dense, Weak>
|
||||||
{
|
{
|
||||||
EIGEN_DEVICE_FUNC
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
|
||||||
static EIGEN_STRONG_INLINE void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
|
|
||||||
{
|
{
|
||||||
#ifndef EIGEN_NO_DEBUG
|
#ifndef EIGEN_NO_DEBUG
|
||||||
internal::check_for_aliasing(dst, src);
|
internal::check_for_aliasing(dst, src);
|
||||||
@@ -962,8 +886,7 @@ struct Assignment<DstXprType, SrcXprType, Functor, Dense2Dense, Weak>
|
|||||||
template< typename DstXprType, typename SrcXprType, typename Functor, typename Weak>
|
template< typename DstXprType, typename SrcXprType, typename Functor, typename Weak>
|
||||||
struct Assignment<DstXprType, SrcXprType, Functor, EigenBase2EigenBase, Weak>
|
struct Assignment<DstXprType, SrcXprType, Functor, EigenBase2EigenBase, Weak>
|
||||||
{
|
{
|
||||||
EIGEN_DEVICE_FUNC
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar> &/*func*/)
|
||||||
static EIGEN_STRONG_INLINE void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar> &/*func*/)
|
|
||||||
{
|
{
|
||||||
Index dstRows = src.rows();
|
Index dstRows = src.rows();
|
||||||
Index dstCols = src.cols();
|
Index dstCols = src.cols();
|
||||||
@@ -974,7 +897,7 @@ struct Assignment<DstXprType, SrcXprType, Functor, EigenBase2EigenBase, Weak>
|
|||||||
src.evalTo(dst);
|
src.evalTo(dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE The following two functions are templated to avoid their instantiation if not needed
|
// NOTE The following two functions are templated to avoid their instanciation if not needed
|
||||||
// This is needed because some expressions supports evalTo only and/or have 'void' as scalar type.
|
// This is needed because some expressions supports evalTo only and/or have 'void' as scalar type.
|
||||||
template<typename SrcScalarType>
|
template<typename SrcScalarType>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
|
|||||||
@@ -68,16 +68,16 @@ class vml_assign_traits
|
|||||||
|
|
||||||
#define EIGEN_PP_EXPAND(ARG) ARG
|
#define EIGEN_PP_EXPAND(ARG) ARG
|
||||||
#if !defined (EIGEN_FAST_MATH) || (EIGEN_FAST_MATH != 1)
|
#if !defined (EIGEN_FAST_MATH) || (EIGEN_FAST_MATH != 1)
|
||||||
#define EIGEN_VMLMODE_EXPAND_xLA , VML_HA
|
#define EIGEN_VMLMODE_EXPAND_LA , VML_HA
|
||||||
#else
|
#else
|
||||||
#define EIGEN_VMLMODE_EXPAND_xLA , VML_LA
|
#define EIGEN_VMLMODE_EXPAND_LA , VML_LA
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define EIGEN_VMLMODE_EXPAND_x_
|
#define EIGEN_VMLMODE_EXPAND__
|
||||||
|
|
||||||
#define EIGEN_VMLMODE_PREFIX_xLA vm
|
#define EIGEN_VMLMODE_PREFIX_LA vm
|
||||||
#define EIGEN_VMLMODE_PREFIX_x_ v
|
#define EIGEN_VMLMODE_PREFIX__ v
|
||||||
#define EIGEN_VMLMODE_PREFIX(VMLMODE) EIGEN_CAT(EIGEN_VMLMODE_PREFIX_x,VMLMODE)
|
#define EIGEN_VMLMODE_PREFIX(VMLMODE) EIGEN_CAT(EIGEN_VMLMODE_PREFIX_,VMLMODE)
|
||||||
|
|
||||||
#define EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE, VMLMODE) \
|
#define EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE, VMLMODE) \
|
||||||
template< typename DstXprType, typename SrcXprNested> \
|
template< typename DstXprType, typename SrcXprNested> \
|
||||||
@@ -89,7 +89,7 @@ class vml_assign_traits
|
|||||||
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols()); \
|
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols()); \
|
||||||
if(vml_assign_traits<DstXprType,SrcXprNested>::Traversal==LinearTraversal) { \
|
if(vml_assign_traits<DstXprType,SrcXprNested>::Traversal==LinearTraversal) { \
|
||||||
VMLOP(dst.size(), (const VMLTYPE*)src.nestedExpression().data(), \
|
VMLOP(dst.size(), (const VMLTYPE*)src.nestedExpression().data(), \
|
||||||
(VMLTYPE*)dst.data() EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_x##VMLMODE) ); \
|
(VMLTYPE*)dst.data() EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_##VMLMODE) ); \
|
||||||
} else { \
|
} else { \
|
||||||
const Index outerSize = dst.outerSize(); \
|
const Index outerSize = dst.outerSize(); \
|
||||||
for(Index outer = 0; outer < outerSize; ++outer) { \
|
for(Index outer = 0; outer < outerSize; ++outer) { \
|
||||||
@@ -97,7 +97,7 @@ class vml_assign_traits
|
|||||||
&(src.nestedExpression().coeffRef(0, outer)); \
|
&(src.nestedExpression().coeffRef(0, outer)); \
|
||||||
EIGENTYPE *dst_ptr = dst.IsRowMajor ? &(dst.coeffRef(outer,0)) : &(dst.coeffRef(0, outer)); \
|
EIGENTYPE *dst_ptr = dst.IsRowMajor ? &(dst.coeffRef(outer,0)) : &(dst.coeffRef(0, outer)); \
|
||||||
VMLOP( dst.innerSize(), (const VMLTYPE*)src_ptr, \
|
VMLOP( dst.innerSize(), (const VMLTYPE*)src_ptr, \
|
||||||
(VMLTYPE*)dst_ptr EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_x##VMLMODE)); \
|
(VMLTYPE*)dst_ptr EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_##VMLMODE)); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
@@ -152,7 +152,7 @@ EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(ceil, Ceil, _)
|
|||||||
if(vml_assign_traits<DstXprType,SrcXprNested>::Traversal==LinearTraversal) \
|
if(vml_assign_traits<DstXprType,SrcXprNested>::Traversal==LinearTraversal) \
|
||||||
{ \
|
{ \
|
||||||
VMLOP( dst.size(), (const VMLTYPE*)src.lhs().data(), exponent, \
|
VMLOP( dst.size(), (const VMLTYPE*)src.lhs().data(), exponent, \
|
||||||
(VMLTYPE*)dst.data() EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_x##VMLMODE) ); \
|
(VMLTYPE*)dst.data() EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_##VMLMODE) ); \
|
||||||
} else { \
|
} else { \
|
||||||
const Index outerSize = dst.outerSize(); \
|
const Index outerSize = dst.outerSize(); \
|
||||||
for(Index outer = 0; outer < outerSize; ++outer) { \
|
for(Index outer = 0; outer < outerSize; ++outer) { \
|
||||||
@@ -160,7 +160,7 @@ EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(ceil, Ceil, _)
|
|||||||
&(src.lhs().coeffRef(0, outer)); \
|
&(src.lhs().coeffRef(0, outer)); \
|
||||||
EIGENTYPE *dst_ptr = dst.IsRowMajor ? &(dst.coeffRef(outer,0)) : &(dst.coeffRef(0, outer)); \
|
EIGENTYPE *dst_ptr = dst.IsRowMajor ? &(dst.coeffRef(outer,0)) : &(dst.coeffRef(0, outer)); \
|
||||||
VMLOP( dst.innerSize(), (const VMLTYPE*)src_ptr, exponent, \
|
VMLOP( dst.innerSize(), (const VMLTYPE*)src_ptr, exponent, \
|
||||||
(VMLTYPE*)dst_ptr EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_x##VMLMODE)); \
|
(VMLTYPE*)dst_ptr EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_##VMLMODE)); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ class BandMatrixBase : public EigenBase<Derived>
|
|||||||
* \warning the internal storage must be column major. */
|
* \warning the internal storage must be column major. */
|
||||||
inline Block<CoefficientsType,Dynamic,1> col(Index i)
|
inline Block<CoefficientsType,Dynamic,1> col(Index i)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT((int(Options) & int(RowMajor)) == 0, THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
|
EIGEN_STATIC_ASSERT((Options&RowMajor)==0,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
|
||||||
Index start = 0;
|
Index start = 0;
|
||||||
Index len = coeffs().rows();
|
Index len = coeffs().rows();
|
||||||
if (i<=supers())
|
if (i<=supers())
|
||||||
@@ -90,7 +90,7 @@ class BandMatrixBase : public EigenBase<Derived>
|
|||||||
|
|
||||||
template<int Index> struct DiagonalIntReturnType {
|
template<int Index> struct DiagonalIntReturnType {
|
||||||
enum {
|
enum {
|
||||||
ReturnOpposite = (int(Options) & int(SelfAdjoint)) && (((Index) > 0 && Supers == 0) || ((Index) < 0 && Subs == 0)),
|
ReturnOpposite = (Options&SelfAdjoint) && (((Index)>0 && Supers==0) || ((Index)<0 && Subs==0)),
|
||||||
Conjugate = ReturnOpposite && NumTraits<Scalar>::IsComplex,
|
Conjugate = ReturnOpposite && NumTraits<Scalar>::IsComplex,
|
||||||
ActualIndex = ReturnOpposite ? -Index : Index,
|
ActualIndex = ReturnOpposite ? -Index : Index,
|
||||||
DiagonalSize = (RowsAtCompileTime==Dynamic || ColsAtCompileTime==Dynamic)
|
DiagonalSize = (RowsAtCompileTime==Dynamic || ColsAtCompileTime==Dynamic)
|
||||||
@@ -192,7 +192,7 @@ struct traits<BandMatrix<_Scalar,_Rows,_Cols,_Supers,_Subs,_Options> >
|
|||||||
Options = _Options,
|
Options = _Options,
|
||||||
DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic
|
DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic
|
||||||
};
|
};
|
||||||
typedef Matrix<Scalar, DataRowsAtCompileTime, ColsAtCompileTime, int(Options) & int(RowMajor) ? RowMajor : ColMajor> CoefficientsType;
|
typedef Matrix<Scalar,DataRowsAtCompileTime,ColsAtCompileTime,Options&RowMajor?RowMajor:ColMajor> CoefficientsType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _Scalar, int Rows, int Cols, int Supers, int Subs, int Options>
|
template<typename _Scalar, int Rows, int Cols, int Supers, int Subs, int Options>
|
||||||
@@ -211,16 +211,16 @@ class BandMatrix : public BandMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Sub
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the number of columns */
|
/** \returns the number of columns */
|
||||||
inline EIGEN_CONSTEXPR Index rows() const { return m_rows.value(); }
|
inline Index rows() const { return m_rows.value(); }
|
||||||
|
|
||||||
/** \returns the number of rows */
|
/** \returns the number of rows */
|
||||||
inline EIGEN_CONSTEXPR Index cols() const { return m_coeffs.cols(); }
|
inline Index cols() const { return m_coeffs.cols(); }
|
||||||
|
|
||||||
/** \returns the number of super diagonals */
|
/** \returns the number of super diagonals */
|
||||||
inline EIGEN_CONSTEXPR Index supers() const { return m_supers.value(); }
|
inline Index supers() const { return m_supers.value(); }
|
||||||
|
|
||||||
/** \returns the number of sub diagonals */
|
/** \returns the number of sub diagonals */
|
||||||
inline EIGEN_CONSTEXPR Index subs() const { return m_subs.value(); }
|
inline Index subs() const { return m_subs.value(); }
|
||||||
|
|
||||||
inline const CoefficientsType& coeffs() const { return m_coeffs; }
|
inline const CoefficientsType& coeffs() const { return m_coeffs; }
|
||||||
inline CoefficientsType& coeffs() { return m_coeffs; }
|
inline CoefficientsType& coeffs() { return m_coeffs; }
|
||||||
@@ -275,16 +275,16 @@ class BandMatrixWrapper : public BandMatrixBase<BandMatrixWrapper<_CoefficientsT
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the number of columns */
|
/** \returns the number of columns */
|
||||||
inline EIGEN_CONSTEXPR Index rows() const { return m_rows.value(); }
|
inline Index rows() const { return m_rows.value(); }
|
||||||
|
|
||||||
/** \returns the number of rows */
|
/** \returns the number of rows */
|
||||||
inline EIGEN_CONSTEXPR Index cols() const { return m_coeffs.cols(); }
|
inline Index cols() const { return m_coeffs.cols(); }
|
||||||
|
|
||||||
/** \returns the number of super diagonals */
|
/** \returns the number of super diagonals */
|
||||||
inline EIGEN_CONSTEXPR Index supers() const { return m_supers.value(); }
|
inline Index supers() const { return m_supers.value(); }
|
||||||
|
|
||||||
/** \returns the number of sub diagonals */
|
/** \returns the number of sub diagonals */
|
||||||
inline EIGEN_CONSTEXPR Index subs() const { return m_subs.value(); }
|
inline Index subs() const { return m_subs.value(); }
|
||||||
|
|
||||||
inline const CoefficientsType& coeffs() const { return m_coeffs; }
|
inline const CoefficientsType& coeffs() const { return m_coeffs; }
|
||||||
|
|
||||||
|
|||||||
@@ -114,8 +114,8 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> class
|
|||||||
|
|
||||||
/** Column or Row constructor
|
/** Column or Row constructor
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
Block(XprType& xpr, Index i) : Impl(xpr,i)
|
inline Block(XprType& xpr, Index i) : Impl(xpr,i)
|
||||||
{
|
{
|
||||||
eigen_assert( (i>=0) && (
|
eigen_assert( (i>=0) && (
|
||||||
((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i<xpr.rows())
|
((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i<xpr.rows())
|
||||||
@@ -124,8 +124,8 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> class
|
|||||||
|
|
||||||
/** Fixed-size constructor
|
/** Fixed-size constructor
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
Block(XprType& xpr, Index startRow, Index startCol)
|
inline Block(XprType& xpr, Index startRow, Index startCol)
|
||||||
: Impl(xpr, startRow, startCol)
|
: Impl(xpr, startRow, startCol)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
|
EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
|
||||||
@@ -135,8 +135,8 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> class
|
|||||||
|
|
||||||
/** Dynamic-size constructor
|
/** Dynamic-size constructor
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
Block(XprType& xpr,
|
inline Block(XprType& xpr,
|
||||||
Index startRow, Index startCol,
|
Index startRow, Index startCol,
|
||||||
Index blockRows, Index blockCols)
|
Index blockRows, Index blockCols)
|
||||||
: Impl(xpr, startRow, startCol, blockRows, blockCols)
|
: Impl(xpr, startRow, startCol, blockRows, blockCols)
|
||||||
@@ -159,10 +159,10 @@ class BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, Dense>
|
|||||||
public:
|
public:
|
||||||
typedef Impl Base;
|
typedef Impl Base;
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl)
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl)
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl(XprType& xpr, Index i) : Impl(xpr,i) {}
|
EIGEN_DEVICE_FUNC inline BlockImpl(XprType& xpr, Index i) : Impl(xpr,i) {}
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl(XprType& xpr, Index startRow, Index startCol) : Impl(xpr, startRow, startCol) {}
|
EIGEN_DEVICE_FUNC inline BlockImpl(XprType& xpr, Index startRow, Index startCol) : Impl(xpr, startRow, startCol) {}
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
EIGEN_STRONG_INLINE BlockImpl(XprType& xpr, Index startRow, Index startCol, Index blockRows, Index blockCols)
|
inline BlockImpl(XprType& xpr, Index startRow, Index startCol, Index blockRows, Index blockCols)
|
||||||
: Impl(xpr, startRow, startCol, blockRows, blockCols) {}
|
: Impl(xpr, startRow, startCol, blockRows, blockCols) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -260,19 +260,19 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool H
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode>
|
template<int LoadMode>
|
||||||
EIGEN_DEVICE_FUNC inline PacketScalar packet(Index rowId, Index colId) const
|
inline PacketScalar packet(Index rowId, Index colId) const
|
||||||
{
|
{
|
||||||
return m_xpr.template packet<Unaligned>(rowId + m_startRow.value(), colId + m_startCol.value());
|
return m_xpr.template packet<Unaligned>(rowId + m_startRow.value(), colId + m_startCol.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode>
|
template<int LoadMode>
|
||||||
EIGEN_DEVICE_FUNC inline void writePacket(Index rowId, Index colId, const PacketScalar& val)
|
inline void writePacket(Index rowId, Index colId, const PacketScalar& val)
|
||||||
{
|
{
|
||||||
m_xpr.template writePacket<Unaligned>(rowId + m_startRow.value(), colId + m_startCol.value(), val);
|
m_xpr.template writePacket<Unaligned>(rowId + m_startRow.value(), colId + m_startCol.value(), val);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode>
|
template<int LoadMode>
|
||||||
EIGEN_DEVICE_FUNC inline PacketScalar packet(Index index) const
|
inline PacketScalar packet(Index index) const
|
||||||
{
|
{
|
||||||
return m_xpr.template packet<Unaligned>
|
return m_xpr.template packet<Unaligned>
|
||||||
(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
|
(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
|
||||||
@@ -280,7 +280,7 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool H
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode>
|
template<int LoadMode>
|
||||||
EIGEN_DEVICE_FUNC inline void writePacket(Index index, const PacketScalar& val)
|
inline void writePacket(Index index, const PacketScalar& val)
|
||||||
{
|
{
|
||||||
m_xpr.template writePacket<Unaligned>
|
m_xpr.template writePacket<Unaligned>
|
||||||
(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
|
(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
|
||||||
@@ -294,23 +294,23 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool H
|
|||||||
EIGEN_DEVICE_FUNC inline Index outerStride() const;
|
EIGEN_DEVICE_FUNC inline Index outerStride() const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
const typename internal::remove_all<XprTypeNested>::type& nestedExpression() const
|
const typename internal::remove_all<XprTypeNested>::type& nestedExpression() const
|
||||||
{
|
{
|
||||||
return m_xpr;
|
return m_xpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
XprType& nestedExpression() { return m_xpr; }
|
XprType& nestedExpression() { return m_xpr; }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
StorageIndex startRow() const EIGEN_NOEXCEPT
|
StorageIndex startRow() const
|
||||||
{
|
{
|
||||||
return m_startRow.value();
|
return m_startRow.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
StorageIndex startCol() const EIGEN_NOEXCEPT
|
StorageIndex startCol() const
|
||||||
{
|
{
|
||||||
return m_startCol.value();
|
return m_startCol.value();
|
||||||
}
|
}
|
||||||
@@ -334,17 +334,6 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
|||||||
enum {
|
enum {
|
||||||
XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0
|
XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \internal Returns base+offset (unless base is null, in which case returns null).
|
|
||||||
* Adding an offset to nullptr is undefined behavior, so we must avoid it.
|
|
||||||
*/
|
|
||||||
template <typename Scalar>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR EIGEN_ALWAYS_INLINE
|
|
||||||
static Scalar* add_to_nullable_pointer(Scalar* base, Index offset)
|
|
||||||
{
|
|
||||||
return base != NULL ? base+offset : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef MapBase<BlockType> Base;
|
typedef MapBase<BlockType> Base;
|
||||||
@@ -353,11 +342,10 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
|||||||
|
|
||||||
/** Column or Row constructor
|
/** Column or Row constructor
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
BlockImpl_dense(XprType& xpr, Index i)
|
inline BlockImpl_dense(XprType& xpr, Index i)
|
||||||
: Base((BlockRows == 0 || BlockCols == 0) ? NULL : add_to_nullable_pointer(xpr.data(),
|
: Base(xpr.data() + i * ( ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && (!XprTypeIsRowMajor))
|
||||||
i * ( ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && (!XprTypeIsRowMajor))
|
|| ((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && ( XprTypeIsRowMajor)) ? xpr.innerStride() : xpr.outerStride()),
|
||||||
|| ((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && ( XprTypeIsRowMajor)) ? xpr.innerStride() : xpr.outerStride())),
|
|
||||||
BlockRows==1 ? 1 : xpr.rows(),
|
BlockRows==1 ? 1 : xpr.rows(),
|
||||||
BlockCols==1 ? 1 : xpr.cols()),
|
BlockCols==1 ? 1 : xpr.cols()),
|
||||||
m_xpr(xpr),
|
m_xpr(xpr),
|
||||||
@@ -369,10 +357,9 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
|||||||
|
|
||||||
/** Fixed-size constructor
|
/** Fixed-size constructor
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
|
inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
|
||||||
: Base((BlockRows == 0 || BlockCols == 0) ? NULL : add_to_nullable_pointer(xpr.data(),
|
: Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol)),
|
||||||
xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol))),
|
|
||||||
m_xpr(xpr), m_startRow(startRow), m_startCol(startCol)
|
m_xpr(xpr), m_startRow(startRow), m_startCol(startCol)
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
@@ -380,30 +367,28 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
|||||||
|
|
||||||
/** Dynamic-size constructor
|
/** Dynamic-size constructor
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
BlockImpl_dense(XprType& xpr,
|
inline BlockImpl_dense(XprType& xpr,
|
||||||
Index startRow, Index startCol,
|
Index startRow, Index startCol,
|
||||||
Index blockRows, Index blockCols)
|
Index blockRows, Index blockCols)
|
||||||
: Base((blockRows == 0 || blockCols == 0) ? NULL : add_to_nullable_pointer(xpr.data(),
|
: Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol), blockRows, blockCols),
|
||||||
xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol)),
|
|
||||||
blockRows, blockCols),
|
|
||||||
m_xpr(xpr), m_startRow(startRow), m_startCol(startCol)
|
m_xpr(xpr), m_startRow(startRow), m_startCol(startCol)
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
const typename internal::remove_all<XprTypeNested>::type& nestedExpression() const EIGEN_NOEXCEPT
|
const typename internal::remove_all<XprTypeNested>::type& nestedExpression() const
|
||||||
{
|
{
|
||||||
return m_xpr;
|
return m_xpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
XprType& nestedExpression() { return m_xpr; }
|
XprType& nestedExpression() { return m_xpr; }
|
||||||
|
|
||||||
/** \sa MapBase::innerStride() */
|
/** \sa MapBase::innerStride() */
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
Index innerStride() const EIGEN_NOEXCEPT
|
inline Index innerStride() const
|
||||||
{
|
{
|
||||||
return internal::traits<BlockType>::HasSameStorageOrderAsXprType
|
return internal::traits<BlockType>::HasSameStorageOrderAsXprType
|
||||||
? m_xpr.innerStride()
|
? m_xpr.innerStride()
|
||||||
@@ -411,19 +396,23 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** \sa MapBase::outerStride() */
|
/** \sa MapBase::outerStride() */
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
Index outerStride() const EIGEN_NOEXCEPT
|
inline Index outerStride() const
|
||||||
{
|
{
|
||||||
return internal::traits<BlockType>::HasSameStorageOrderAsXprType
|
return m_outerStride;
|
||||||
? m_xpr.outerStride()
|
|
||||||
: m_xpr.innerStride();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
StorageIndex startRow() const EIGEN_NOEXCEPT { return m_startRow.value(); }
|
StorageIndex startRow() const
|
||||||
|
{
|
||||||
|
return m_startRow.value();
|
||||||
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
StorageIndex startCol() const EIGEN_NOEXCEPT { return m_startCol.value(); }
|
StorageIndex startCol() const
|
||||||
|
{
|
||||||
|
return m_startCol.value();
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef __SUNPRO_CC
|
#ifndef __SUNPRO_CC
|
||||||
// FIXME sunstudio is not friendly with the above friend...
|
// FIXME sunstudio is not friendly with the above friend...
|
||||||
@@ -433,8 +422,8 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
|||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
/** \internal used by allowAligned() */
|
/** \internal used by allowAligned() */
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
BlockImpl_dense(XprType& xpr, const Scalar* data, Index blockRows, Index blockCols)
|
inline BlockImpl_dense(XprType& xpr, const Scalar* data, Index blockRows, Index blockCols)
|
||||||
: Base(data, blockRows, blockCols), m_xpr(xpr)
|
: Base(data, blockRows, blockCols), m_xpr(xpr)
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
@@ -442,7 +431,7 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
m_outerStride = internal::traits<BlockType>::HasSameStorageOrderAsXprType
|
m_outerStride = internal::traits<BlockType>::HasSameStorageOrderAsXprType
|
||||||
|
|||||||
@@ -14,56 +14,56 @@ namespace Eigen {
|
|||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template<typename Derived, int UnrollCount, int InnerSize>
|
template<typename Derived, int UnrollCount>
|
||||||
struct all_unroller
|
struct all_unroller
|
||||||
{
|
{
|
||||||
|
typedef typename Derived::ExpressionTraits Traits;
|
||||||
enum {
|
enum {
|
||||||
IsRowMajor = (int(Derived::Flags) & int(RowMajor)),
|
col = (UnrollCount-1) / Traits::RowsAtCompileTime,
|
||||||
i = (UnrollCount-1) / InnerSize,
|
row = (UnrollCount-1) % Traits::RowsAtCompileTime
|
||||||
j = (UnrollCount-1) % InnerSize
|
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC static inline bool run(const Derived &mat)
|
EIGEN_DEVICE_FUNC static inline bool run(const Derived &mat)
|
||||||
{
|
{
|
||||||
return all_unroller<Derived, UnrollCount-1, InnerSize>::run(mat) && mat.coeff(IsRowMajor ? i : j, IsRowMajor ? j : i);
|
return all_unroller<Derived, UnrollCount-1>::run(mat) && mat.coeff(row, col);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived, int InnerSize>
|
template<typename Derived>
|
||||||
struct all_unroller<Derived, 0, InnerSize>
|
struct all_unroller<Derived, 0>
|
||||||
{
|
{
|
||||||
EIGEN_DEVICE_FUNC static inline bool run(const Derived &/*mat*/) { return true; }
|
EIGEN_DEVICE_FUNC static inline bool run(const Derived &/*mat*/) { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived, int InnerSize>
|
template<typename Derived>
|
||||||
struct all_unroller<Derived, Dynamic, InnerSize>
|
struct all_unroller<Derived, Dynamic>
|
||||||
{
|
{
|
||||||
EIGEN_DEVICE_FUNC static inline bool run(const Derived &) { return false; }
|
EIGEN_DEVICE_FUNC static inline bool run(const Derived &) { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived, int UnrollCount, int InnerSize>
|
template<typename Derived, int UnrollCount>
|
||||||
struct any_unroller
|
struct any_unroller
|
||||||
{
|
{
|
||||||
|
typedef typename Derived::ExpressionTraits Traits;
|
||||||
enum {
|
enum {
|
||||||
IsRowMajor = (int(Derived::Flags) & int(RowMajor)),
|
col = (UnrollCount-1) / Traits::RowsAtCompileTime,
|
||||||
i = (UnrollCount-1) / InnerSize,
|
row = (UnrollCount-1) % Traits::RowsAtCompileTime
|
||||||
j = (UnrollCount-1) % InnerSize
|
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC static inline bool run(const Derived &mat)
|
EIGEN_DEVICE_FUNC static inline bool run(const Derived &mat)
|
||||||
{
|
{
|
||||||
return any_unroller<Derived, UnrollCount-1, InnerSize>::run(mat) || mat.coeff(IsRowMajor ? i : j, IsRowMajor ? j : i);
|
return any_unroller<Derived, UnrollCount-1>::run(mat) || mat.coeff(row, col);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived, int InnerSize>
|
template<typename Derived>
|
||||||
struct any_unroller<Derived, 0, InnerSize>
|
struct any_unroller<Derived, 0>
|
||||||
{
|
{
|
||||||
EIGEN_DEVICE_FUNC static inline bool run(const Derived & /*mat*/) { return false; }
|
EIGEN_DEVICE_FUNC static inline bool run(const Derived & /*mat*/) { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived, int InnerSize>
|
template<typename Derived>
|
||||||
struct any_unroller<Derived, Dynamic, InnerSize>
|
struct any_unroller<Derived, Dynamic>
|
||||||
{
|
{
|
||||||
EIGEN_DEVICE_FUNC static inline bool run(const Derived &) { return false; }
|
EIGEN_DEVICE_FUNC static inline bool run(const Derived &) { return false; }
|
||||||
};
|
};
|
||||||
@@ -83,16 +83,16 @@ EIGEN_DEVICE_FUNC inline bool DenseBase<Derived>::all() const
|
|||||||
typedef internal::evaluator<Derived> Evaluator;
|
typedef internal::evaluator<Derived> Evaluator;
|
||||||
enum {
|
enum {
|
||||||
unroll = SizeAtCompileTime != Dynamic
|
unroll = SizeAtCompileTime != Dynamic
|
||||||
&& SizeAtCompileTime * (int(Evaluator::CoeffReadCost) + int(NumTraits<Scalar>::AddCost)) <= EIGEN_UNROLLING_LIMIT
|
&& SizeAtCompileTime * (Evaluator::CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
|
||||||
};
|
};
|
||||||
Evaluator evaluator(derived());
|
Evaluator evaluator(derived());
|
||||||
if(unroll)
|
if(unroll)
|
||||||
return internal::all_unroller<Evaluator, unroll ? int(SizeAtCompileTime) : Dynamic, InnerSizeAtCompileTime>::run(evaluator);
|
return internal::all_unroller<Evaluator, unroll ? int(SizeAtCompileTime) : Dynamic>::run(evaluator);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(Index i = 0; i < derived().outerSize(); ++i)
|
for(Index j = 0; j < cols(); ++j)
|
||||||
for(Index j = 0; j < derived().innerSize(); ++j)
|
for(Index i = 0; i < rows(); ++i)
|
||||||
if (!evaluator.coeff(IsRowMajor ? i : j, IsRowMajor ? j : i)) return false;
|
if (!evaluator.coeff(i, j)) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,16 +107,16 @@ EIGEN_DEVICE_FUNC inline bool DenseBase<Derived>::any() const
|
|||||||
typedef internal::evaluator<Derived> Evaluator;
|
typedef internal::evaluator<Derived> Evaluator;
|
||||||
enum {
|
enum {
|
||||||
unroll = SizeAtCompileTime != Dynamic
|
unroll = SizeAtCompileTime != Dynamic
|
||||||
&& SizeAtCompileTime * (int(Evaluator::CoeffReadCost) + int(NumTraits<Scalar>::AddCost)) <= EIGEN_UNROLLING_LIMIT
|
&& SizeAtCompileTime * (Evaluator::CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
|
||||||
};
|
};
|
||||||
Evaluator evaluator(derived());
|
Evaluator evaluator(derived());
|
||||||
if(unroll)
|
if(unroll)
|
||||||
return internal::any_unroller<Evaluator, unroll ? int(SizeAtCompileTime) : Dynamic, InnerSizeAtCompileTime>::run(evaluator);
|
return internal::any_unroller<Evaluator, unroll ? int(SizeAtCompileTime) : Dynamic>::run(evaluator);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(Index i = 0; i < derived().outerSize(); ++i)
|
for(Index j = 0; j < cols(); ++j)
|
||||||
for(Index j = 0; j < derived().innerSize(); ++j)
|
for(Index i = 0; i < rows(); ++i)
|
||||||
if (evaluator.coeff(IsRowMajor ? i : j, IsRowMajor ? j : i)) return true;
|
if (evaluator.coeff(i, j)) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,8 +33,6 @@ struct CommaInitializer
|
|||||||
inline CommaInitializer(XprType& xpr, const Scalar& s)
|
inline CommaInitializer(XprType& xpr, const Scalar& s)
|
||||||
: m_xpr(xpr), m_row(0), m_col(1), m_currentBlockRows(1)
|
: m_xpr(xpr), m_row(0), m_col(1), m_currentBlockRows(1)
|
||||||
{
|
{
|
||||||
eigen_assert(m_xpr.rows() > 0 && m_xpr.cols() > 0
|
|
||||||
&& "Cannot comma-initialize a 0x0 matrix (operator<<)");
|
|
||||||
m_xpr.coeffRef(0,0) = s;
|
m_xpr.coeffRef(0,0) = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,8 +41,6 @@ struct CommaInitializer
|
|||||||
inline CommaInitializer(XprType& xpr, const DenseBase<OtherDerived>& other)
|
inline CommaInitializer(XprType& xpr, const DenseBase<OtherDerived>& other)
|
||||||
: m_xpr(xpr), m_row(0), m_col(other.cols()), m_currentBlockRows(other.rows())
|
: m_xpr(xpr), m_row(0), m_col(other.cols()), m_currentBlockRows(other.rows())
|
||||||
{
|
{
|
||||||
eigen_assert(m_xpr.rows() >= other.rows() && m_xpr.cols() >= other.cols()
|
|
||||||
&& "Cannot comma-initialize a 0x0 matrix (operator<<)");
|
|
||||||
m_xpr.block(0, 0, other.rows(), other.cols()) = other;
|
m_xpr.block(0, 0, other.rows(), other.cols()) = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +103,7 @@ struct CommaInitializer
|
|||||||
EIGEN_EXCEPTION_SPEC(Eigen::eigen_assert_exception)
|
EIGEN_EXCEPTION_SPEC(Eigen::eigen_assert_exception)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
finished();
|
finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the built matrix once all its coefficients have been set.
|
/** \returns the built matrix once all its coefficients have been set.
|
||||||
|
|||||||
@@ -90,8 +90,7 @@ template<typename T>
|
|||||||
struct evaluator : public unary_evaluator<T>
|
struct evaluator : public unary_evaluator<T>
|
||||||
{
|
{
|
||||||
typedef unary_evaluator<T> Base;
|
typedef unary_evaluator<T> Base;
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC explicit evaluator(const T& xpr) : Base(xpr) {}
|
||||||
explicit evaluator(const T& xpr) : Base(xpr) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -100,14 +99,14 @@ template<typename T>
|
|||||||
struct evaluator<const T>
|
struct evaluator<const T>
|
||||||
: evaluator<T>
|
: evaluator<T>
|
||||||
{
|
{
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
explicit evaluator(const T& xpr) : evaluator<T>(xpr) {}
|
explicit evaluator(const T& xpr) : evaluator<T>(xpr) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------- base class for all evaluators ----------
|
// ---------- base class for all evaluators ----------
|
||||||
|
|
||||||
template<typename ExpressionType>
|
template<typename ExpressionType>
|
||||||
struct evaluator_base
|
struct evaluator_base : public noncopyable
|
||||||
{
|
{
|
||||||
// TODO that's not very nice to have to propagate all these traits. They are currently only needed to handle outer,inner indices.
|
// TODO that's not very nice to have to propagate all these traits. They are currently only needed to handle outer,inner indices.
|
||||||
typedef traits<ExpressionType> ExpressionTraits;
|
typedef traits<ExpressionType> ExpressionTraits;
|
||||||
@@ -115,14 +114,6 @@ struct evaluator_base
|
|||||||
enum {
|
enum {
|
||||||
Alignment = 0
|
Alignment = 0
|
||||||
};
|
};
|
||||||
// noncopyable:
|
|
||||||
// Don't make this class inherit noncopyable as this kills EBO (Empty Base Optimization)
|
|
||||||
// and make complex evaluator much larger than then should do.
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE evaluator_base() {}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ~evaluator_base() {}
|
|
||||||
private:
|
|
||||||
EIGEN_DEVICE_FUNC evaluator_base(const evaluator_base&);
|
|
||||||
EIGEN_DEVICE_FUNC const evaluator_base& operator=(const evaluator_base&);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------- Matrix and Array --------------------
|
// -------------------- Matrix and Array --------------------
|
||||||
@@ -132,33 +123,6 @@ private:
|
|||||||
// Here we directly specialize evaluator. This is not really a unary expression, and it is, by definition, dense,
|
// Here we directly specialize evaluator. This is not really a unary expression, and it is, by definition, dense,
|
||||||
// so no need for more sophisticated dispatching.
|
// so no need for more sophisticated dispatching.
|
||||||
|
|
||||||
// this helper permits to completely eliminate m_outerStride if it is known at compiletime.
|
|
||||||
template<typename Scalar,int OuterStride> class plainobjectbase_evaluator_data {
|
|
||||||
public:
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
plainobjectbase_evaluator_data(const Scalar* ptr, Index outerStride) : data(ptr)
|
|
||||||
{
|
|
||||||
#ifndef EIGEN_INTERNAL_DEBUGGING
|
|
||||||
EIGEN_UNUSED_VARIABLE(outerStride);
|
|
||||||
#endif
|
|
||||||
eigen_internal_assert(outerStride==OuterStride);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
|
||||||
Index outerStride() const EIGEN_NOEXCEPT { return OuterStride; }
|
|
||||||
const Scalar *data;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Scalar> class plainobjectbase_evaluator_data<Scalar,Dynamic> {
|
|
||||||
public:
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
plainobjectbase_evaluator_data(const Scalar* ptr, Index outerStride) : data(ptr), m_outerStride(outerStride) {}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
Index outerStride() const { return m_outerStride; }
|
|
||||||
const Scalar *data;
|
|
||||||
protected:
|
|
||||||
Index m_outerStride;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
struct evaluator<PlainObjectBase<Derived> >
|
struct evaluator<PlainObjectBase<Derived> >
|
||||||
: evaluator_base<Derived>
|
: evaluator_base<Derived>
|
||||||
@@ -177,23 +141,18 @@ struct evaluator<PlainObjectBase<Derived> >
|
|||||||
Flags = traits<Derived>::EvaluatorFlags,
|
Flags = traits<Derived>::EvaluatorFlags,
|
||||||
Alignment = traits<Derived>::Alignment
|
Alignment = traits<Derived>::Alignment
|
||||||
};
|
};
|
||||||
enum {
|
|
||||||
// We do not need to know the outer stride for vectors
|
|
||||||
OuterStrideAtCompileTime = IsVectorAtCompileTime ? 0
|
|
||||||
: int(IsRowMajor) ? ColsAtCompileTime
|
|
||||||
: RowsAtCompileTime
|
|
||||||
};
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC evaluator()
|
||||||
evaluator()
|
: m_data(0),
|
||||||
: m_d(0,OuterStrideAtCompileTime)
|
m_outerStride(IsVectorAtCompileTime ? 0
|
||||||
|
: int(IsRowMajor) ? ColsAtCompileTime
|
||||||
|
: RowsAtCompileTime)
|
||||||
{
|
{
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC explicit evaluator(const PlainObjectType& m)
|
||||||
explicit evaluator(const PlainObjectType& m)
|
: m_data(m.data()), m_outerStride(IsVectorAtCompileTime ? 0 : m.outerStride())
|
||||||
: m_d(m.data(),IsVectorAtCompileTime ? 0 : m.outerStride())
|
|
||||||
{
|
{
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
||||||
}
|
}
|
||||||
@@ -202,30 +161,30 @@ struct evaluator<PlainObjectBase<Derived> >
|
|||||||
CoeffReturnType coeff(Index row, Index col) const
|
CoeffReturnType coeff(Index row, Index col) const
|
||||||
{
|
{
|
||||||
if (IsRowMajor)
|
if (IsRowMajor)
|
||||||
return m_d.data[row * m_d.outerStride() + col];
|
return m_data[row * m_outerStride.value() + col];
|
||||||
else
|
else
|
||||||
return m_d.data[row + col * m_d.outerStride()];
|
return m_data[row + col * m_outerStride.value()];
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
CoeffReturnType coeff(Index index) const
|
CoeffReturnType coeff(Index index) const
|
||||||
{
|
{
|
||||||
return m_d.data[index];
|
return m_data[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
Scalar& coeffRef(Index row, Index col)
|
Scalar& coeffRef(Index row, Index col)
|
||||||
{
|
{
|
||||||
if (IsRowMajor)
|
if (IsRowMajor)
|
||||||
return const_cast<Scalar*>(m_d.data)[row * m_d.outerStride() + col];
|
return const_cast<Scalar*>(m_data)[row * m_outerStride.value() + col];
|
||||||
else
|
else
|
||||||
return const_cast<Scalar*>(m_d.data)[row + col * m_d.outerStride()];
|
return const_cast<Scalar*>(m_data)[row + col * m_outerStride.value()];
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
Scalar& coeffRef(Index index)
|
Scalar& coeffRef(Index index)
|
||||||
{
|
{
|
||||||
return const_cast<Scalar*>(m_d.data)[index];
|
return const_cast<Scalar*>(m_data)[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
template<int LoadMode, typename PacketType>
|
||||||
@@ -233,16 +192,16 @@ struct evaluator<PlainObjectBase<Derived> >
|
|||||||
PacketType packet(Index row, Index col) const
|
PacketType packet(Index row, Index col) const
|
||||||
{
|
{
|
||||||
if (IsRowMajor)
|
if (IsRowMajor)
|
||||||
return ploadt<PacketType, LoadMode>(m_d.data + row * m_d.outerStride() + col);
|
return ploadt<PacketType, LoadMode>(m_data + row * m_outerStride.value() + col);
|
||||||
else
|
else
|
||||||
return ploadt<PacketType, LoadMode>(m_d.data + row + col * m_d.outerStride());
|
return ploadt<PacketType, LoadMode>(m_data + row + col * m_outerStride.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
template<int LoadMode, typename PacketType>
|
||||||
EIGEN_STRONG_INLINE
|
EIGEN_STRONG_INLINE
|
||||||
PacketType packet(Index index) const
|
PacketType packet(Index index) const
|
||||||
{
|
{
|
||||||
return ploadt<PacketType, LoadMode>(m_d.data + index);
|
return ploadt<PacketType, LoadMode>(m_data + index);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int StoreMode,typename PacketType>
|
template<int StoreMode,typename PacketType>
|
||||||
@@ -251,22 +210,26 @@ struct evaluator<PlainObjectBase<Derived> >
|
|||||||
{
|
{
|
||||||
if (IsRowMajor)
|
if (IsRowMajor)
|
||||||
return pstoret<Scalar, PacketType, StoreMode>
|
return pstoret<Scalar, PacketType, StoreMode>
|
||||||
(const_cast<Scalar*>(m_d.data) + row * m_d.outerStride() + col, x);
|
(const_cast<Scalar*>(m_data) + row * m_outerStride.value() + col, x);
|
||||||
else
|
else
|
||||||
return pstoret<Scalar, PacketType, StoreMode>
|
return pstoret<Scalar, PacketType, StoreMode>
|
||||||
(const_cast<Scalar*>(m_d.data) + row + col * m_d.outerStride(), x);
|
(const_cast<Scalar*>(m_data) + row + col * m_outerStride.value(), x);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int StoreMode, typename PacketType>
|
template<int StoreMode, typename PacketType>
|
||||||
EIGEN_STRONG_INLINE
|
EIGEN_STRONG_INLINE
|
||||||
void writePacket(Index index, const PacketType& x)
|
void writePacket(Index index, const PacketType& x)
|
||||||
{
|
{
|
||||||
return pstoret<Scalar, PacketType, StoreMode>(const_cast<Scalar*>(m_d.data) + index, x);
|
return pstoret<Scalar, PacketType, StoreMode>(const_cast<Scalar*>(m_data) + index, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
const Scalar *m_data;
|
||||||
|
|
||||||
plainobjectbase_evaluator_data<Scalar,OuterStrideAtCompileTime> m_d;
|
// We do not need to know the outer stride for vectors
|
||||||
|
variable_if_dynamic<Index, IsVectorAtCompileTime ? 0
|
||||||
|
: int(IsRowMajor) ? ColsAtCompileTime
|
||||||
|
: RowsAtCompileTime> m_outerStride;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
|
template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
|
||||||
@@ -275,11 +238,9 @@ struct evaluator<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
|
|||||||
{
|
{
|
||||||
typedef Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> XprType;
|
typedef Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> XprType;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC evaluator() {}
|
||||||
evaluator() {}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC explicit evaluator(const XprType& m)
|
||||||
explicit evaluator(const XprType& m)
|
|
||||||
: evaluator<PlainObjectBase<XprType> >(m)
|
: evaluator<PlainObjectBase<XprType> >(m)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
@@ -290,11 +251,9 @@ struct evaluator<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
|
|||||||
{
|
{
|
||||||
typedef Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> XprType;
|
typedef Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> XprType;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC evaluator() {}
|
||||||
evaluator() {}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC explicit evaluator(const XprType& m)
|
||||||
explicit evaluator(const XprType& m)
|
|
||||||
: evaluator<PlainObjectBase<XprType> >(m)
|
: evaluator<PlainObjectBase<XprType> >(m)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
@@ -313,8 +272,7 @@ struct unary_evaluator<Transpose<ArgType>, IndexBased>
|
|||||||
Alignment = evaluator<ArgType>::Alignment
|
Alignment = evaluator<ArgType>::Alignment
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& t) : m_argImpl(t.nestedExpression()) {}
|
||||||
explicit unary_evaluator(const XprType& t) : m_argImpl(t.nestedExpression()) {}
|
|
||||||
|
|
||||||
typedef typename XprType::Scalar Scalar;
|
typedef typename XprType::Scalar Scalar;
|
||||||
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
||||||
@@ -561,7 +519,7 @@ struct unary_evaluator<CwiseUnaryOp<UnaryOp, ArgType>, IndexBased >
|
|||||||
typedef CwiseUnaryOp<UnaryOp, ArgType> XprType;
|
typedef CwiseUnaryOp<UnaryOp, ArgType> XprType;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CoeffReadCost = int(evaluator<ArgType>::CoeffReadCost) + int(functor_traits<UnaryOp>::Cost),
|
CoeffReadCost = evaluator<ArgType>::CoeffReadCost + functor_traits<UnaryOp>::Cost,
|
||||||
|
|
||||||
Flags = evaluator<ArgType>::Flags
|
Flags = evaluator<ArgType>::Flags
|
||||||
& (HereditaryBits | LinearAccessBit | (functor_traits<UnaryOp>::PacketAccess ? PacketAccessBit : 0)),
|
& (HereditaryBits | LinearAccessBit | (functor_traits<UnaryOp>::PacketAccess ? PacketAccessBit : 0)),
|
||||||
@@ -569,7 +527,9 @@ struct unary_evaluator<CwiseUnaryOp<UnaryOp, ArgType>, IndexBased >
|
|||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
explicit unary_evaluator(const XprType& op) : m_d(op)
|
explicit unary_evaluator(const XprType& op)
|
||||||
|
: m_functor(op.functor()),
|
||||||
|
m_argImpl(op.nestedExpression())
|
||||||
{
|
{
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<UnaryOp>::Cost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<UnaryOp>::Cost);
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
||||||
@@ -580,43 +540,32 @@ struct unary_evaluator<CwiseUnaryOp<UnaryOp, ArgType>, IndexBased >
|
|||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
CoeffReturnType coeff(Index row, Index col) const
|
CoeffReturnType coeff(Index row, Index col) const
|
||||||
{
|
{
|
||||||
return m_d.func()(m_d.argImpl.coeff(row, col));
|
return m_functor(m_argImpl.coeff(row, col));
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
CoeffReturnType coeff(Index index) const
|
CoeffReturnType coeff(Index index) const
|
||||||
{
|
{
|
||||||
return m_d.func()(m_d.argImpl.coeff(index));
|
return m_functor(m_argImpl.coeff(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
template<int LoadMode, typename PacketType>
|
||||||
EIGEN_STRONG_INLINE
|
EIGEN_STRONG_INLINE
|
||||||
PacketType packet(Index row, Index col) const
|
PacketType packet(Index row, Index col) const
|
||||||
{
|
{
|
||||||
return m_d.func().packetOp(m_d.argImpl.template packet<LoadMode, PacketType>(row, col));
|
return m_functor.packetOp(m_argImpl.template packet<LoadMode, PacketType>(row, col));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
template<int LoadMode, typename PacketType>
|
||||||
EIGEN_STRONG_INLINE
|
EIGEN_STRONG_INLINE
|
||||||
PacketType packet(Index index) const
|
PacketType packet(Index index) const
|
||||||
{
|
{
|
||||||
return m_d.func().packetOp(m_d.argImpl.template packet<LoadMode, PacketType>(index));
|
return m_functor.packetOp(m_argImpl.template packet<LoadMode, PacketType>(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
const UnaryOp m_functor;
|
||||||
// this helper permits to completely eliminate the functor if it is empty
|
evaluator<ArgType> m_argImpl;
|
||||||
struct Data
|
|
||||||
{
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
Data(const XprType& xpr) : op(xpr.functor()), argImpl(xpr.nestedExpression()) {}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
const UnaryOp& func() const { return op; }
|
|
||||||
UnaryOp op;
|
|
||||||
evaluator<ArgType> argImpl;
|
|
||||||
};
|
|
||||||
|
|
||||||
Data m_d;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------- CwiseTernaryOp --------------------
|
// -------------------- CwiseTernaryOp --------------------
|
||||||
@@ -639,7 +588,7 @@ struct ternary_evaluator<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>, IndexBased
|
|||||||
typedef CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> XprType;
|
typedef CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> XprType;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CoeffReadCost = int(evaluator<Arg1>::CoeffReadCost) + int(evaluator<Arg2>::CoeffReadCost) + int(evaluator<Arg3>::CoeffReadCost) + int(functor_traits<TernaryOp>::Cost),
|
CoeffReadCost = evaluator<Arg1>::CoeffReadCost + evaluator<Arg2>::CoeffReadCost + evaluator<Arg3>::CoeffReadCost + functor_traits<TernaryOp>::Cost,
|
||||||
|
|
||||||
Arg1Flags = evaluator<Arg1>::Flags,
|
Arg1Flags = evaluator<Arg1>::Flags,
|
||||||
Arg2Flags = evaluator<Arg2>::Flags,
|
Arg2Flags = evaluator<Arg2>::Flags,
|
||||||
@@ -660,7 +609,11 @@ struct ternary_evaluator<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>, IndexBased
|
|||||||
evaluator<Arg3>::Alignment)
|
evaluator<Arg3>::Alignment)
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit ternary_evaluator(const XprType& xpr) : m_d(xpr)
|
EIGEN_DEVICE_FUNC explicit ternary_evaluator(const XprType& xpr)
|
||||||
|
: m_functor(xpr.functor()),
|
||||||
|
m_arg1Impl(xpr.arg1()),
|
||||||
|
m_arg2Impl(xpr.arg2()),
|
||||||
|
m_arg3Impl(xpr.arg3())
|
||||||
{
|
{
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<TernaryOp>::Cost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<TernaryOp>::Cost);
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
||||||
@@ -671,48 +624,38 @@ struct ternary_evaluator<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>, IndexBased
|
|||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
CoeffReturnType coeff(Index row, Index col) const
|
CoeffReturnType coeff(Index row, Index col) const
|
||||||
{
|
{
|
||||||
return m_d.func()(m_d.arg1Impl.coeff(row, col), m_d.arg2Impl.coeff(row, col), m_d.arg3Impl.coeff(row, col));
|
return m_functor(m_arg1Impl.coeff(row, col), m_arg2Impl.coeff(row, col), m_arg3Impl.coeff(row, col));
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
CoeffReturnType coeff(Index index) const
|
CoeffReturnType coeff(Index index) const
|
||||||
{
|
{
|
||||||
return m_d.func()(m_d.arg1Impl.coeff(index), m_d.arg2Impl.coeff(index), m_d.arg3Impl.coeff(index));
|
return m_functor(m_arg1Impl.coeff(index), m_arg2Impl.coeff(index), m_arg3Impl.coeff(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
template<int LoadMode, typename PacketType>
|
||||||
EIGEN_STRONG_INLINE
|
EIGEN_STRONG_INLINE
|
||||||
PacketType packet(Index row, Index col) const
|
PacketType packet(Index row, Index col) const
|
||||||
{
|
{
|
||||||
return m_d.func().packetOp(m_d.arg1Impl.template packet<LoadMode,PacketType>(row, col),
|
return m_functor.packetOp(m_arg1Impl.template packet<LoadMode,PacketType>(row, col),
|
||||||
m_d.arg2Impl.template packet<LoadMode,PacketType>(row, col),
|
m_arg2Impl.template packet<LoadMode,PacketType>(row, col),
|
||||||
m_d.arg3Impl.template packet<LoadMode,PacketType>(row, col));
|
m_arg3Impl.template packet<LoadMode,PacketType>(row, col));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
template<int LoadMode, typename PacketType>
|
||||||
EIGEN_STRONG_INLINE
|
EIGEN_STRONG_INLINE
|
||||||
PacketType packet(Index index) const
|
PacketType packet(Index index) const
|
||||||
{
|
{
|
||||||
return m_d.func().packetOp(m_d.arg1Impl.template packet<LoadMode,PacketType>(index),
|
return m_functor.packetOp(m_arg1Impl.template packet<LoadMode,PacketType>(index),
|
||||||
m_d.arg2Impl.template packet<LoadMode,PacketType>(index),
|
m_arg2Impl.template packet<LoadMode,PacketType>(index),
|
||||||
m_d.arg3Impl.template packet<LoadMode,PacketType>(index));
|
m_arg3Impl.template packet<LoadMode,PacketType>(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// this helper permits to completely eliminate the functor if it is empty
|
const TernaryOp m_functor;
|
||||||
struct Data
|
evaluator<Arg1> m_arg1Impl;
|
||||||
{
|
evaluator<Arg2> m_arg2Impl;
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
evaluator<Arg3> m_arg3Impl;
|
||||||
Data(const XprType& xpr) : op(xpr.functor()), arg1Impl(xpr.arg1()), arg2Impl(xpr.arg2()), arg3Impl(xpr.arg3()) {}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
const TernaryOp& func() const { return op; }
|
|
||||||
TernaryOp op;
|
|
||||||
evaluator<Arg1> arg1Impl;
|
|
||||||
evaluator<Arg2> arg2Impl;
|
|
||||||
evaluator<Arg3> arg3Impl;
|
|
||||||
};
|
|
||||||
|
|
||||||
Data m_d;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------- CwiseBinaryOp --------------------
|
// -------------------- CwiseBinaryOp --------------------
|
||||||
@@ -725,8 +668,7 @@ struct evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
|
|||||||
typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
|
typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
|
||||||
typedef binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > Base;
|
typedef binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > Base;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr) : Base(xpr) {}
|
||||||
explicit evaluator(const XprType& xpr) : Base(xpr) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BinaryOp, typename Lhs, typename Rhs>
|
template<typename BinaryOp, typename Lhs, typename Rhs>
|
||||||
@@ -736,7 +678,7 @@ struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>, IndexBased, IndexBase
|
|||||||
typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
|
typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CoeffReadCost = int(evaluator<Lhs>::CoeffReadCost) + int(evaluator<Rhs>::CoeffReadCost) + int(functor_traits<BinaryOp>::Cost),
|
CoeffReadCost = evaluator<Lhs>::CoeffReadCost + evaluator<Rhs>::CoeffReadCost + functor_traits<BinaryOp>::Cost,
|
||||||
|
|
||||||
LhsFlags = evaluator<Lhs>::Flags,
|
LhsFlags = evaluator<Lhs>::Flags,
|
||||||
RhsFlags = evaluator<Rhs>::Flags,
|
RhsFlags = evaluator<Rhs>::Flags,
|
||||||
@@ -754,8 +696,10 @@ struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>, IndexBased, IndexBase
|
|||||||
Alignment = EIGEN_PLAIN_ENUM_MIN(evaluator<Lhs>::Alignment,evaluator<Rhs>::Alignment)
|
Alignment = EIGEN_PLAIN_ENUM_MIN(evaluator<Lhs>::Alignment,evaluator<Rhs>::Alignment)
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC explicit binary_evaluator(const XprType& xpr)
|
||||||
explicit binary_evaluator(const XprType& xpr) : m_d(xpr)
|
: m_functor(xpr.functor()),
|
||||||
|
m_lhsImpl(xpr.lhs()),
|
||||||
|
m_rhsImpl(xpr.rhs())
|
||||||
{
|
{
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
||||||
@@ -766,46 +710,35 @@ struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>, IndexBased, IndexBase
|
|||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
CoeffReturnType coeff(Index row, Index col) const
|
CoeffReturnType coeff(Index row, Index col) const
|
||||||
{
|
{
|
||||||
return m_d.func()(m_d.lhsImpl.coeff(row, col), m_d.rhsImpl.coeff(row, col));
|
return m_functor(m_lhsImpl.coeff(row, col), m_rhsImpl.coeff(row, col));
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
CoeffReturnType coeff(Index index) const
|
CoeffReturnType coeff(Index index) const
|
||||||
{
|
{
|
||||||
return m_d.func()(m_d.lhsImpl.coeff(index), m_d.rhsImpl.coeff(index));
|
return m_functor(m_lhsImpl.coeff(index), m_rhsImpl.coeff(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
template<int LoadMode, typename PacketType>
|
||||||
EIGEN_STRONG_INLINE
|
EIGEN_STRONG_INLINE
|
||||||
PacketType packet(Index row, Index col) const
|
PacketType packet(Index row, Index col) const
|
||||||
{
|
{
|
||||||
return m_d.func().packetOp(m_d.lhsImpl.template packet<LoadMode,PacketType>(row, col),
|
return m_functor.packetOp(m_lhsImpl.template packet<LoadMode,PacketType>(row, col),
|
||||||
m_d.rhsImpl.template packet<LoadMode,PacketType>(row, col));
|
m_rhsImpl.template packet<LoadMode,PacketType>(row, col));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
template<int LoadMode, typename PacketType>
|
||||||
EIGEN_STRONG_INLINE
|
EIGEN_STRONG_INLINE
|
||||||
PacketType packet(Index index) const
|
PacketType packet(Index index) const
|
||||||
{
|
{
|
||||||
return m_d.func().packetOp(m_d.lhsImpl.template packet<LoadMode,PacketType>(index),
|
return m_functor.packetOp(m_lhsImpl.template packet<LoadMode,PacketType>(index),
|
||||||
m_d.rhsImpl.template packet<LoadMode,PacketType>(index));
|
m_rhsImpl.template packet<LoadMode,PacketType>(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
const BinaryOp m_functor;
|
||||||
// this helper permits to completely eliminate the functor if it is empty
|
evaluator<Lhs> m_lhsImpl;
|
||||||
struct Data
|
evaluator<Rhs> m_rhsImpl;
|
||||||
{
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
Data(const XprType& xpr) : op(xpr.functor()), lhsImpl(xpr.lhs()), rhsImpl(xpr.rhs()) {}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
const BinaryOp& func() const { return op; }
|
|
||||||
BinaryOp op;
|
|
||||||
evaluator<Lhs> lhsImpl;
|
|
||||||
evaluator<Rhs> rhsImpl;
|
|
||||||
};
|
|
||||||
|
|
||||||
Data m_d;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------- CwiseUnaryView --------------------
|
// -------------------- CwiseUnaryView --------------------
|
||||||
@@ -817,14 +750,16 @@ struct unary_evaluator<CwiseUnaryView<UnaryOp, ArgType>, IndexBased>
|
|||||||
typedef CwiseUnaryView<UnaryOp, ArgType> XprType;
|
typedef CwiseUnaryView<UnaryOp, ArgType> XprType;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CoeffReadCost = int(evaluator<ArgType>::CoeffReadCost) + int(functor_traits<UnaryOp>::Cost),
|
CoeffReadCost = evaluator<ArgType>::CoeffReadCost + functor_traits<UnaryOp>::Cost,
|
||||||
|
|
||||||
Flags = (evaluator<ArgType>::Flags & (HereditaryBits | LinearAccessBit | DirectAccessBit)),
|
Flags = (evaluator<ArgType>::Flags & (HereditaryBits | LinearAccessBit | DirectAccessBit)),
|
||||||
|
|
||||||
Alignment = 0 // FIXME it is not very clear why alignment is necessarily lost...
|
Alignment = 0 // FIXME it is not very clear why alignment is necessarily lost...
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& op) : m_d(op)
|
EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& op)
|
||||||
|
: m_unaryOp(op.functor()),
|
||||||
|
m_argImpl(op.nestedExpression())
|
||||||
{
|
{
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<UnaryOp>::Cost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<UnaryOp>::Cost);
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
||||||
@@ -836,41 +771,30 @@ struct unary_evaluator<CwiseUnaryView<UnaryOp, ArgType>, IndexBased>
|
|||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
CoeffReturnType coeff(Index row, Index col) const
|
CoeffReturnType coeff(Index row, Index col) const
|
||||||
{
|
{
|
||||||
return m_d.func()(m_d.argImpl.coeff(row, col));
|
return m_unaryOp(m_argImpl.coeff(row, col));
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
CoeffReturnType coeff(Index index) const
|
CoeffReturnType coeff(Index index) const
|
||||||
{
|
{
|
||||||
return m_d.func()(m_d.argImpl.coeff(index));
|
return m_unaryOp(m_argImpl.coeff(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
Scalar& coeffRef(Index row, Index col)
|
Scalar& coeffRef(Index row, Index col)
|
||||||
{
|
{
|
||||||
return m_d.func()(m_d.argImpl.coeffRef(row, col));
|
return m_unaryOp(m_argImpl.coeffRef(row, col));
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
Scalar& coeffRef(Index index)
|
Scalar& coeffRef(Index index)
|
||||||
{
|
{
|
||||||
return m_d.func()(m_d.argImpl.coeffRef(index));
|
return m_unaryOp(m_argImpl.coeffRef(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
const UnaryOp m_unaryOp;
|
||||||
// this helper permits to completely eliminate the functor if it is empty
|
evaluator<ArgType> m_argImpl;
|
||||||
struct Data
|
|
||||||
{
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
Data(const XprType& xpr) : op(xpr.functor()), argImpl(xpr.nestedExpression()) {}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
const UnaryOp& func() const { return op; }
|
|
||||||
UnaryOp op;
|
|
||||||
evaluator<ArgType> argImpl;
|
|
||||||
};
|
|
||||||
|
|
||||||
Data m_d;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------- Map --------------------
|
// -------------------- Map --------------------
|
||||||
@@ -894,8 +818,7 @@ struct mapbase_evaluator : evaluator_base<Derived>
|
|||||||
CoeffReadCost = NumTraits<Scalar>::ReadCost
|
CoeffReadCost = NumTraits<Scalar>::ReadCost
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC explicit mapbase_evaluator(const XprType& map)
|
||||||
explicit mapbase_evaluator(const XprType& map)
|
|
||||||
: m_data(const_cast<PointerType>(map.data())),
|
: m_data(const_cast<PointerType>(map.data())),
|
||||||
m_innerStride(map.innerStride()),
|
m_innerStride(map.innerStride()),
|
||||||
m_outerStride(map.outerStride())
|
m_outerStride(map.outerStride())
|
||||||
@@ -959,14 +882,10 @@ struct mapbase_evaluator : evaluator_base<Derived>
|
|||||||
internal::pstoret<Scalar, PacketType, StoreMode>(m_data + index * m_innerStride.value(), x);
|
internal::pstoret<Scalar, PacketType, StoreMode>(m_data + index * m_innerStride.value(), x);
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
Index rowStride() const EIGEN_NOEXCEPT {
|
inline Index rowStride() const { return XprType::IsRowMajor ? m_outerStride.value() : m_innerStride.value(); }
|
||||||
return XprType::IsRowMajor ? m_outerStride.value() : m_innerStride.value();
|
EIGEN_DEVICE_FUNC
|
||||||
}
|
inline Index colStride() const { return XprType::IsRowMajor ? m_innerStride.value() : m_outerStride.value(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
|
||||||
Index colStride() const EIGEN_NOEXCEPT {
|
|
||||||
return XprType::IsRowMajor ? m_innerStride.value() : m_outerStride.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
PointerType m_data;
|
PointerType m_data;
|
||||||
const internal::variable_if_dynamic<Index, XprType::InnerStrideAtCompileTime> m_innerStride;
|
const internal::variable_if_dynamic<Index, XprType::InnerStrideAtCompileTime> m_innerStride;
|
||||||
@@ -1019,8 +938,7 @@ struct evaluator<Ref<PlainObjectType, RefOptions, StrideType> >
|
|||||||
Alignment = evaluator<Map<PlainObjectType, RefOptions, StrideType> >::Alignment
|
Alignment = evaluator<Map<PlainObjectType, RefOptions, StrideType> >::Alignment
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC explicit evaluator(const XprType& ref)
|
||||||
explicit evaluator(const XprType& ref)
|
|
||||||
: mapbase_evaluator<XprType, PlainObjectType>(ref)
|
: mapbase_evaluator<XprType, PlainObjectType>(ref)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
@@ -1075,8 +993,7 @@ struct evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel> >
|
|||||||
Alignment = EIGEN_PLAIN_ENUM_MIN(evaluator<ArgType>::Alignment, Alignment0)
|
Alignment = EIGEN_PLAIN_ENUM_MIN(evaluator<ArgType>::Alignment, Alignment0)
|
||||||
};
|
};
|
||||||
typedef block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel> block_evaluator_type;
|
typedef block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel> block_evaluator_type;
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC explicit evaluator(const XprType& block) : block_evaluator_type(block)
|
||||||
explicit evaluator(const XprType& block) : block_evaluator_type(block)
|
|
||||||
{
|
{
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
||||||
}
|
}
|
||||||
@@ -1089,8 +1006,7 @@ struct block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel, /*HasDirectAcc
|
|||||||
{
|
{
|
||||||
typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
|
typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC explicit block_evaluator(const XprType& block)
|
||||||
explicit block_evaluator(const XprType& block)
|
|
||||||
: unary_evaluator<XprType>(block)
|
: unary_evaluator<XprType>(block)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
@@ -1101,12 +1017,11 @@ struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IndexBa
|
|||||||
{
|
{
|
||||||
typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
|
typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& block)
|
||||||
explicit unary_evaluator(const XprType& block)
|
|
||||||
: m_argImpl(block.nestedExpression()),
|
: m_argImpl(block.nestedExpression()),
|
||||||
m_startRow(block.startRow()),
|
m_startRow(block.startRow()),
|
||||||
m_startCol(block.startCol()),
|
m_startCol(block.startCol()),
|
||||||
m_linear_offset(ForwardLinearAccess?(ArgType::IsRowMajor ? block.startRow()*block.nestedExpression().cols() + block.startCol() : block.startCol()*block.nestedExpression().rows() + block.startRow()):0)
|
m_linear_offset(InnerPanel?(XprType::IsRowMajor ? block.startRow()*block.cols() : block.startCol()*block.rows()):0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
typedef typename XprType::Scalar Scalar;
|
typedef typename XprType::Scalar Scalar;
|
||||||
@@ -1114,7 +1029,7 @@ struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IndexBa
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
RowsAtCompileTime = XprType::RowsAtCompileTime,
|
RowsAtCompileTime = XprType::RowsAtCompileTime,
|
||||||
ForwardLinearAccess = (InnerPanel || int(XprType::IsRowMajor)==int(ArgType::IsRowMajor)) && bool(evaluator<ArgType>::Flags&LinearAccessBit)
|
ForwardLinearAccess = InnerPanel && bool(evaluator<ArgType>::Flags&LinearAccessBit)
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
@@ -1126,7 +1041,10 @@ struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IndexBa
|
|||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
CoeffReturnType coeff(Index index) const
|
CoeffReturnType coeff(Index index) const
|
||||||
{
|
{
|
||||||
return linear_coeff_impl(index, bool_constant<ForwardLinearAccess>());
|
if (ForwardLinearAccess)
|
||||||
|
return m_argImpl.coeff(m_linear_offset.value() + index);
|
||||||
|
else
|
||||||
|
return coeff(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
@@ -1138,7 +1056,10 @@ struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IndexBa
|
|||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
Scalar& coeffRef(Index index)
|
Scalar& coeffRef(Index index)
|
||||||
{
|
{
|
||||||
return linear_coeffRef_impl(index, bool_constant<ForwardLinearAccess>());
|
if (ForwardLinearAccess)
|
||||||
|
return m_argImpl.coeffRef(m_linear_offset.value() + index);
|
||||||
|
else
|
||||||
|
return coeffRef(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
template<int LoadMode, typename PacketType>
|
||||||
@@ -1179,32 +1100,10 @@ struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IndexBa
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
CoeffReturnType linear_coeff_impl(Index index, internal::true_type /* ForwardLinearAccess */) const
|
|
||||||
{
|
|
||||||
return m_argImpl.coeff(m_linear_offset.value() + index);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
CoeffReturnType linear_coeff_impl(Index index, internal::false_type /* not ForwardLinearAccess */) const
|
|
||||||
{
|
|
||||||
return coeff(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
Scalar& linear_coeffRef_impl(Index index, internal::true_type /* ForwardLinearAccess */)
|
|
||||||
{
|
|
||||||
return m_argImpl.coeffRef(m_linear_offset.value() + index);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
Scalar& linear_coeffRef_impl(Index index, internal::false_type /* not ForwardLinearAccess */)
|
|
||||||
{
|
|
||||||
return coeffRef(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
evaluator<ArgType> m_argImpl;
|
evaluator<ArgType> m_argImpl;
|
||||||
const variable_if_dynamic<Index, (ArgType::RowsAtCompileTime == 1 && BlockRows==1) ? 0 : Dynamic> m_startRow;
|
const variable_if_dynamic<Index, (ArgType::RowsAtCompileTime == 1 && BlockRows==1) ? 0 : Dynamic> m_startRow;
|
||||||
const variable_if_dynamic<Index, (ArgType::ColsAtCompileTime == 1 && BlockCols==1) ? 0 : Dynamic> m_startCol;
|
const variable_if_dynamic<Index, (ArgType::ColsAtCompileTime == 1 && BlockCols==1) ? 0 : Dynamic> m_startCol;
|
||||||
const variable_if_dynamic<Index, ForwardLinearAccess ? Dynamic : 0> m_linear_offset;
|
const variable_if_dynamic<Index, InnerPanel ? Dynamic : 0> m_linear_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: This evaluator does not actually use the child evaluator;
|
// TODO: This evaluator does not actually use the child evaluator;
|
||||||
@@ -1218,8 +1117,7 @@ struct block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel, /* HasDirectAc
|
|||||||
typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
|
typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
|
||||||
typedef typename XprType::Scalar Scalar;
|
typedef typename XprType::Scalar Scalar;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC explicit block_evaluator(const XprType& block)
|
||||||
explicit block_evaluator(const XprType& block)
|
|
||||||
: mapbase_evaluator<XprType, typename XprType::PlainObject>(block)
|
: mapbase_evaluator<XprType, typename XprType::PlainObject>(block)
|
||||||
{
|
{
|
||||||
// TODO: for the 3.3 release, this should be turned to an internal assertion, but let's keep it as is for the beta lifetime
|
// TODO: for the 3.3 release, this should be turned to an internal assertion, but let's keep it as is for the beta lifetime
|
||||||
@@ -1247,8 +1145,7 @@ struct evaluator<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >
|
|||||||
Alignment = EIGEN_PLAIN_ENUM_MIN(evaluator<ThenMatrixType>::Alignment, evaluator<ElseMatrixType>::Alignment)
|
Alignment = EIGEN_PLAIN_ENUM_MIN(evaluator<ThenMatrixType>::Alignment, evaluator<ElseMatrixType>::Alignment)
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC explicit evaluator(const XprType& select)
|
||||||
explicit evaluator(const XprType& select)
|
|
||||||
: m_conditionImpl(select.conditionMatrix()),
|
: m_conditionImpl(select.conditionMatrix()),
|
||||||
m_thenImpl(select.thenMatrix()),
|
m_thenImpl(select.thenMatrix()),
|
||||||
m_elseImpl(select.elseMatrix())
|
m_elseImpl(select.elseMatrix())
|
||||||
@@ -1305,8 +1202,7 @@ struct unary_evaluator<Replicate<ArgType, RowFactor, ColFactor> >
|
|||||||
Alignment = evaluator<ArgTypeNestedCleaned>::Alignment
|
Alignment = evaluator<ArgTypeNestedCleaned>::Alignment
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& replicate)
|
||||||
explicit unary_evaluator(const XprType& replicate)
|
|
||||||
: m_arg(replicate.nestedExpression()),
|
: m_arg(replicate.nestedExpression()),
|
||||||
m_argImpl(m_arg),
|
m_argImpl(m_arg),
|
||||||
m_rows(replicate.nestedExpression().rows()),
|
m_rows(replicate.nestedExpression().rows()),
|
||||||
@@ -1370,6 +1266,64 @@ protected:
|
|||||||
const variable_if_dynamic<Index, ArgType::ColsAtCompileTime> m_cols;
|
const variable_if_dynamic<Index, ArgType::ColsAtCompileTime> m_cols;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------- PartialReduxExpr --------------------
|
||||||
|
|
||||||
|
template< typename ArgType, typename MemberOp, int Direction>
|
||||||
|
struct evaluator<PartialReduxExpr<ArgType, MemberOp, Direction> >
|
||||||
|
: evaluator_base<PartialReduxExpr<ArgType, MemberOp, Direction> >
|
||||||
|
{
|
||||||
|
typedef PartialReduxExpr<ArgType, MemberOp, Direction> XprType;
|
||||||
|
typedef typename internal::nested_eval<ArgType,1>::type ArgTypeNested;
|
||||||
|
typedef typename internal::remove_all<ArgTypeNested>::type ArgTypeNestedCleaned;
|
||||||
|
typedef typename ArgType::Scalar InputScalar;
|
||||||
|
typedef typename XprType::Scalar Scalar;
|
||||||
|
enum {
|
||||||
|
TraversalSize = Direction==int(Vertical) ? int(ArgType::RowsAtCompileTime) : int(ArgType::ColsAtCompileTime)
|
||||||
|
};
|
||||||
|
typedef typename MemberOp::template Cost<InputScalar,int(TraversalSize)> CostOpType;
|
||||||
|
enum {
|
||||||
|
CoeffReadCost = TraversalSize==Dynamic ? HugeCost
|
||||||
|
: TraversalSize * evaluator<ArgType>::CoeffReadCost + int(CostOpType::value),
|
||||||
|
|
||||||
|
Flags = (traits<XprType>::Flags&RowMajorBit) | (evaluator<ArgType>::Flags&(HereditaryBits&(~RowMajorBit))) | LinearAccessBit,
|
||||||
|
|
||||||
|
Alignment = 0 // FIXME this will need to be improved once PartialReduxExpr is vectorized
|
||||||
|
};
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC explicit evaluator(const XprType xpr)
|
||||||
|
: m_arg(xpr.nestedExpression()), m_functor(xpr.functor())
|
||||||
|
{
|
||||||
|
EIGEN_INTERNAL_CHECK_COST_VALUE(TraversalSize==Dynamic ? HugeCost : int(CostOpType::value));
|
||||||
|
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
const Scalar coeff(Index i, Index j) const
|
||||||
|
{
|
||||||
|
if (Direction==Vertical)
|
||||||
|
return m_functor(m_arg.col(j));
|
||||||
|
else
|
||||||
|
return m_functor(m_arg.row(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
const Scalar coeff(Index index) const
|
||||||
|
{
|
||||||
|
if (Direction==Vertical)
|
||||||
|
return m_functor(m_arg.col(index));
|
||||||
|
else
|
||||||
|
return m_functor(m_arg.row(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
typename internal::add_const_on_value_type<ArgTypeNested>::type m_arg;
|
||||||
|
const MemberOp m_functor;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// -------------------- MatrixWrapper and ArrayWrapper --------------------
|
// -------------------- MatrixWrapper and ArrayWrapper --------------------
|
||||||
//
|
//
|
||||||
// evaluator_wrapper_base<T> is a common base class for the
|
// evaluator_wrapper_base<T> is a common base class for the
|
||||||
@@ -1386,8 +1340,7 @@ struct evaluator_wrapper_base
|
|||||||
Alignment = evaluator<ArgType>::Alignment
|
Alignment = evaluator<ArgType>::Alignment
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC explicit evaluator_wrapper_base(const ArgType& arg) : m_argImpl(arg) {}
|
||||||
explicit evaluator_wrapper_base(const ArgType& arg) : m_argImpl(arg) {}
|
|
||||||
|
|
||||||
typedef typename ArgType::Scalar Scalar;
|
typedef typename ArgType::Scalar Scalar;
|
||||||
typedef typename ArgType::CoeffReturnType CoeffReturnType;
|
typedef typename ArgType::CoeffReturnType CoeffReturnType;
|
||||||
@@ -1454,8 +1407,7 @@ struct unary_evaluator<MatrixWrapper<TArgType> >
|
|||||||
{
|
{
|
||||||
typedef MatrixWrapper<TArgType> XprType;
|
typedef MatrixWrapper<TArgType> XprType;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& wrapper)
|
||||||
explicit unary_evaluator(const XprType& wrapper)
|
|
||||||
: evaluator_wrapper_base<MatrixWrapper<TArgType> >(wrapper.nestedExpression())
|
: evaluator_wrapper_base<MatrixWrapper<TArgType> >(wrapper.nestedExpression())
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
@@ -1466,8 +1418,7 @@ struct unary_evaluator<ArrayWrapper<TArgType> >
|
|||||||
{
|
{
|
||||||
typedef ArrayWrapper<TArgType> XprType;
|
typedef ArrayWrapper<TArgType> XprType;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& wrapper)
|
||||||
explicit unary_evaluator(const XprType& wrapper)
|
|
||||||
: evaluator_wrapper_base<ArrayWrapper<TArgType> >(wrapper.nestedExpression())
|
: evaluator_wrapper_base<ArrayWrapper<TArgType> >(wrapper.nestedExpression())
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
@@ -1509,8 +1460,7 @@ struct unary_evaluator<Reverse<ArgType, Direction> >
|
|||||||
Alignment = 0 // FIXME in some rare cases, Alignment could be preserved, like a Vector4f.
|
Alignment = 0 // FIXME in some rare cases, Alignment could be preserved, like a Vector4f.
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& reverse)
|
||||||
explicit unary_evaluator(const XprType& reverse)
|
|
||||||
: m_argImpl(reverse.nestedExpression()),
|
: m_argImpl(reverse.nestedExpression()),
|
||||||
m_rows(ReverseRow ? reverse.nestedExpression().rows() : 1),
|
m_rows(ReverseRow ? reverse.nestedExpression().rows() : 1),
|
||||||
m_cols(ReverseCol ? reverse.nestedExpression().cols() : 1)
|
m_cols(ReverseCol ? reverse.nestedExpression().cols() : 1)
|
||||||
@@ -1617,8 +1567,7 @@ struct evaluator<Diagonal<ArgType, DiagIndex> >
|
|||||||
Alignment = 0
|
Alignment = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC explicit evaluator(const XprType& diagonal)
|
||||||
explicit evaluator(const XprType& diagonal)
|
|
||||||
: m_argImpl(diagonal.nestedExpression()),
|
: m_argImpl(diagonal.nestedExpression()),
|
||||||
m_index(diagonal.index())
|
m_index(diagonal.index())
|
||||||
{ }
|
{ }
|
||||||
@@ -1655,10 +1604,8 @@ protected:
|
|||||||
const internal::variable_if_dynamicindex<Index, XprType::DiagIndex> m_index;
|
const internal::variable_if_dynamicindex<Index, XprType::DiagIndex> m_index;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rowOffset() const { return m_index.value() > 0 ? 0 : -m_index.value(); }
|
||||||
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; }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
|
||||||
Index colOffset() const { return m_index.value() > 0 ? m_index.value() : 0; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1695,12 +1642,12 @@ class EvalToTemp
|
|||||||
return m_arg;
|
return m_arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
|
Index rows() const
|
||||||
{
|
{
|
||||||
return m_arg.rows();
|
return m_arg.rows();
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT
|
Index cols() const
|
||||||
{
|
{
|
||||||
return m_arg.cols();
|
return m_arg.cols();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,11 +48,6 @@ public:
|
|||||||
* Explicit zeros are not skipped over. To skip explicit zeros, see class SparseView
|
* Explicit zeros are not skipped over. To skip explicit zeros, see class SparseView
|
||||||
*/
|
*/
|
||||||
EIGEN_STRONG_INLINE InnerIterator& operator++() { m_iter.operator++(); return *this; }
|
EIGEN_STRONG_INLINE InnerIterator& operator++() { m_iter.operator++(); return *this; }
|
||||||
EIGEN_STRONG_INLINE InnerIterator& operator+=(Index i) { m_iter.operator+=(i); return *this; }
|
|
||||||
EIGEN_STRONG_INLINE InnerIterator operator+(Index i)
|
|
||||||
{ InnerIterator result(*this); result+=i; return result; }
|
|
||||||
|
|
||||||
|
|
||||||
/// \returns the column or row index of the current coefficient.
|
/// \returns the column or row index of the current coefficient.
|
||||||
EIGEN_STRONG_INLINE Index index() const { return m_iter.index(); }
|
EIGEN_STRONG_INLINE Index index() const { return m_iter.index(); }
|
||||||
/// \returns the row index of the current coefficient.
|
/// \returns the row index of the current coefficient.
|
||||||
|
|||||||
@@ -100,14 +100,8 @@ class CwiseBinaryOp :
|
|||||||
typedef typename internal::remove_reference<LhsNested>::type _LhsNested;
|
typedef typename internal::remove_reference<LhsNested>::type _LhsNested;
|
||||||
typedef typename internal::remove_reference<RhsNested>::type _RhsNested;
|
typedef typename internal::remove_reference<RhsNested>::type _RhsNested;
|
||||||
|
|
||||||
#if EIGEN_COMP_MSVC && EIGEN_HAS_CXX11
|
EIGEN_DEVICE_FUNC
|
||||||
//Required for Visual Studio or the Copy constructor will probably not get inlined!
|
EIGEN_STRONG_INLINE CwiseBinaryOp(const Lhs& aLhs, const Rhs& aRhs, const BinaryOp& func = BinaryOp())
|
||||||
EIGEN_STRONG_INLINE
|
|
||||||
CwiseBinaryOp(const CwiseBinaryOp<BinaryOp,LhsType,RhsType>&) = default;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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)
|
: m_lhs(aLhs), m_rhs(aRhs), m_functor(func)
|
||||||
{
|
{
|
||||||
EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename Rhs::Scalar);
|
EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename Rhs::Scalar);
|
||||||
@@ -116,25 +110,31 @@ class CwiseBinaryOp :
|
|||||||
eigen_assert(aLhs.rows() == aRhs.rows() && aLhs.cols() == aRhs.cols());
|
eigen_assert(aLhs.rows() == aRhs.rows() && aLhs.cols() == aRhs.cols());
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
Index rows() const EIGEN_NOEXCEPT {
|
EIGEN_STRONG_INLINE Index rows() const {
|
||||||
// return the fixed size type if available to enable compile time optimizations
|
// return the fixed size type if available to enable compile time optimizations
|
||||||
return internal::traits<typename internal::remove_all<LhsNested>::type>::RowsAtCompileTime==Dynamic ? m_rhs.rows() : m_lhs.rows();
|
if (internal::traits<typename internal::remove_all<LhsNested>::type>::RowsAtCompileTime==Dynamic)
|
||||||
|
return m_rhs.rows();
|
||||||
|
else
|
||||||
|
return m_lhs.rows();
|
||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
Index cols() const EIGEN_NOEXCEPT {
|
EIGEN_STRONG_INLINE Index cols() const {
|
||||||
// return the fixed size type if available to enable compile time optimizations
|
// return the fixed size type if available to enable compile time optimizations
|
||||||
return internal::traits<typename internal::remove_all<LhsNested>::type>::ColsAtCompileTime==Dynamic ? m_rhs.cols() : m_lhs.cols();
|
if (internal::traits<typename internal::remove_all<LhsNested>::type>::ColsAtCompileTime==Dynamic)
|
||||||
|
return m_rhs.cols();
|
||||||
|
else
|
||||||
|
return m_lhs.cols();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the left hand side nested expression */
|
/** \returns the left hand side nested expression */
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
const _LhsNested& lhs() const { return m_lhs; }
|
const _LhsNested& lhs() const { return m_lhs; }
|
||||||
/** \returns the right hand side nested expression */
|
/** \returns the right hand side nested expression */
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
const _RhsNested& rhs() const { return m_rhs; }
|
const _RhsNested& rhs() const { return m_rhs; }
|
||||||
/** \returns the functor representing the binary operation */
|
/** \returns the functor representing the binary operation */
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
const BinaryOp& functor() const { return m_functor; }
|
const BinaryOp& functor() const { return m_functor; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -181,3 +181,4 @@ MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other)
|
|||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_CWISE_BINARY_OP_H
|
#endif // EIGEN_CWISE_BINARY_OP_H
|
||||||
|
|
||||||
|
|||||||
@@ -74,10 +74,10 @@ class CwiseNullaryOp : public internal::dense_xpr_base< CwiseNullaryOp<NullaryOp
|
|||||||
&& (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
|
&& (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
Index rows() const { return m_rows.value(); }
|
EIGEN_STRONG_INLINE Index rows() const { return m_rows.value(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
Index cols() const { return m_cols.value(); }
|
EIGEN_STRONG_INLINE Index cols() const { return m_cols.value(); }
|
||||||
|
|
||||||
/** \returns the functor representing the nullary operation */
|
/** \returns the functor representing the nullary operation */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
@@ -105,12 +105,7 @@ class CwiseNullaryOp : public internal::dense_xpr_base< CwiseNullaryOp<NullaryOp
|
|||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename CustomNullaryOp>
|
template<typename CustomNullaryOp>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
const CwiseNullaryOp<CustomNullaryOp,typename DenseBase<Derived>::PlainObject>
|
|
||||||
#else
|
|
||||||
const CwiseNullaryOp<CustomNullaryOp,PlainObject>
|
|
||||||
#endif
|
|
||||||
DenseBase<Derived>::NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func)
|
DenseBase<Derived>::NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func)
|
||||||
{
|
{
|
||||||
return CwiseNullaryOp<CustomNullaryOp, PlainObject>(rows, cols, func);
|
return CwiseNullaryOp<CustomNullaryOp, PlainObject>(rows, cols, func);
|
||||||
@@ -136,12 +131,7 @@ DenseBase<Derived>::NullaryExpr(Index rows, Index cols, const CustomNullaryOp& f
|
|||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename CustomNullaryOp>
|
template<typename CustomNullaryOp>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
|
|
||||||
#else
|
|
||||||
const CwiseNullaryOp<CustomNullaryOp, PlainObject>
|
|
||||||
#endif
|
|
||||||
DenseBase<Derived>::NullaryExpr(Index size, const CustomNullaryOp& func)
|
DenseBase<Derived>::NullaryExpr(Index size, const CustomNullaryOp& func)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
@@ -160,12 +150,7 @@ DenseBase<Derived>::NullaryExpr(Index size, const CustomNullaryOp& func)
|
|||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename CustomNullaryOp>
|
template<typename CustomNullaryOp>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
|
|
||||||
#else
|
|
||||||
const CwiseNullaryOp<CustomNullaryOp, PlainObject>
|
|
||||||
#endif
|
|
||||||
DenseBase<Derived>::NullaryExpr(const CustomNullaryOp& func)
|
DenseBase<Derived>::NullaryExpr(const CustomNullaryOp& func)
|
||||||
{
|
{
|
||||||
return CwiseNullaryOp<CustomNullaryOp, PlainObject>(RowsAtCompileTime, ColsAtCompileTime, func);
|
return CwiseNullaryOp<CustomNullaryOp, PlainObject>(RowsAtCompileTime, ColsAtCompileTime, func);
|
||||||
@@ -232,32 +217,27 @@ DenseBase<Derived>::Constant(const Scalar& value)
|
|||||||
|
|
||||||
/** \deprecated because of accuracy loss. In Eigen 3.3, it is an alias for LinSpaced(Index,const Scalar&,const Scalar&)
|
/** \deprecated because of accuracy loss. In Eigen 3.3, it is an alias for LinSpaced(Index,const Scalar&,const Scalar&)
|
||||||
*
|
*
|
||||||
* \only_for_vectors
|
* \sa LinSpaced(Index,Scalar,Scalar), setLinSpaced(Index,const Scalar&,const Scalar&)
|
||||||
*
|
|
||||||
* Example: \include DenseBase_LinSpaced_seq_deprecated.cpp
|
|
||||||
* Output: \verbinclude DenseBase_LinSpaced_seq_deprecated.out
|
|
||||||
*
|
|
||||||
* \sa LinSpaced(Index,const Scalar&, const Scalar&), setLinSpaced(Index,const Scalar&,const Scalar&)
|
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
|
||||||
DenseBase<Derived>::LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high)
|
DenseBase<Derived>::LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar>(low,high,size));
|
return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar,PacketScalar>(low,high,size));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \deprecated because of accuracy loss. In Eigen 3.3, it is an alias for LinSpaced(const Scalar&,const Scalar&)
|
/** \deprecated because of accuracy loss. In Eigen 3.3, it is an alias for LinSpaced(const Scalar&,const Scalar&)
|
||||||
*
|
*
|
||||||
* \sa LinSpaced(const Scalar&, const Scalar&)
|
* \sa LinSpaced(Scalar,Scalar)
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
|
||||||
DenseBase<Derived>::LinSpaced(Sequential_t, const Scalar& low, const Scalar& high)
|
DenseBase<Derived>::LinSpaced(Sequential_t, const Scalar& low, const Scalar& high)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
|
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
|
||||||
return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar>(low,high,Derived::SizeAtCompileTime));
|
return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar,PacketScalar>(low,high,Derived::SizeAtCompileTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -288,7 +268,7 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomA
|
|||||||
DenseBase<Derived>::LinSpaced(Index size, const Scalar& low, const Scalar& high)
|
DenseBase<Derived>::LinSpaced(Index size, const Scalar& low, const Scalar& high)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar>(low,high,size));
|
return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar,PacketScalar>(low,high,size));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -301,7 +281,7 @@ DenseBase<Derived>::LinSpaced(const Scalar& low, const Scalar& high)
|
|||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
|
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
|
||||||
return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar>(low,high,Derived::SizeAtCompileTime));
|
return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar,PacketScalar>(low,high,Derived::SizeAtCompileTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns true if all coefficients in this matrix are approximately equal to \a val, to within precision \a prec */
|
/** \returns true if all coefficients in this matrix are approximately equal to \a val, to within precision \a prec */
|
||||||
@@ -383,33 +363,6 @@ PlainObjectBase<Derived>::setConstant(Index rows, Index cols, const Scalar& val)
|
|||||||
return setConstant(val);
|
return setConstant(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Resizes to the given size, changing only the number of columns, and sets all
|
|
||||||
* coefficients in this expression to the given value \a val. For the parameter
|
|
||||||
* of type NoChange_t, just pass the special value \c NoChange.
|
|
||||||
*
|
|
||||||
* \sa MatrixBase::setConstant(const Scalar&), setConstant(Index,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&)
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
|
|
||||||
PlainObjectBase<Derived>::setConstant(NoChange_t, Index cols, const Scalar& val)
|
|
||||||
{
|
|
||||||
return setConstant(rows(), cols, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Resizes to the given size, changing only the number of rows, and sets all
|
|
||||||
* coefficients in this expression to the given value \a val. For the parameter
|
|
||||||
* of type NoChange_t, just pass the special value \c NoChange.
|
|
||||||
*
|
|
||||||
* \sa MatrixBase::setConstant(const Scalar&), setConstant(Index,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&)
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
|
|
||||||
PlainObjectBase<Derived>::setConstant(Index rows, NoChange_t, const Scalar& val)
|
|
||||||
{
|
|
||||||
return setConstant(rows, cols(), val);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Sets a linearly spaced vector.
|
* \brief Sets a linearly spaced vector.
|
||||||
*
|
*
|
||||||
@@ -430,7 +383,7 @@ template<typename Derived>
|
|||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(Index newSize, const Scalar& low, const Scalar& high)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(Index newSize, const Scalar& low, const Scalar& high)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
return derived() = Derived::NullaryExpr(newSize, internal::linspaced_op<Scalar>(low,high,newSize));
|
return derived() = Derived::NullaryExpr(newSize, internal::linspaced_op<Scalar,PacketScalar>(low,high,newSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -583,32 +536,6 @@ PlainObjectBase<Derived>::setZero(Index rows, Index cols)
|
|||||||
return setConstant(Scalar(0));
|
return setConstant(Scalar(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Resizes to the given size, changing only the number of columns, and sets all
|
|
||||||
* coefficients in this expression to zero. For the parameter of type NoChange_t,
|
|
||||||
* just pass the special value \c NoChange.
|
|
||||||
*
|
|
||||||
* \sa DenseBase::setZero(), setZero(Index), setZero(Index, Index), setZero(Index, NoChange_t), class CwiseNullaryOp, DenseBase::Zero()
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
|
|
||||||
PlainObjectBase<Derived>::setZero(NoChange_t, Index cols)
|
|
||||||
{
|
|
||||||
return setZero(rows(), cols);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Resizes to the given size, changing only the number of rows, and sets all
|
|
||||||
* coefficients in this expression to zero. For the parameter of type NoChange_t,
|
|
||||||
* just pass the special value \c NoChange.
|
|
||||||
*
|
|
||||||
* \sa DenseBase::setZero(), setZero(Index), setZero(Index, Index), setZero(NoChange_t, Index), class CwiseNullaryOp, DenseBase::Zero()
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
|
|
||||||
PlainObjectBase<Derived>::setZero(Index rows, NoChange_t)
|
|
||||||
{
|
|
||||||
return setZero(rows, cols());
|
|
||||||
}
|
|
||||||
|
|
||||||
// ones:
|
// ones:
|
||||||
|
|
||||||
/** \returns an expression of a matrix where all coefficients equal one.
|
/** \returns an expression of a matrix where all coefficients equal one.
|
||||||
@@ -735,32 +662,6 @@ PlainObjectBase<Derived>::setOnes(Index rows, Index cols)
|
|||||||
return setConstant(Scalar(1));
|
return setConstant(Scalar(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Resizes to the given size, changing only the number of rows, and sets all
|
|
||||||
* coefficients in this expression to one. For the parameter of type NoChange_t,
|
|
||||||
* just pass the special value \c NoChange.
|
|
||||||
*
|
|
||||||
* \sa MatrixBase::setOnes(), setOnes(Index), setOnes(Index, Index), setOnes(NoChange_t, Index), class CwiseNullaryOp, MatrixBase::Ones()
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
|
|
||||||
PlainObjectBase<Derived>::setOnes(Index rows, NoChange_t)
|
|
||||||
{
|
|
||||||
return setOnes(rows, cols());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Resizes to the given size, changing only the number of columns, and sets all
|
|
||||||
* coefficients in this expression to one. For the parameter of type NoChange_t,
|
|
||||||
* just pass the special value \c NoChange.
|
|
||||||
*
|
|
||||||
* \sa MatrixBase::setOnes(), setOnes(Index), setOnes(Index, Index), setOnes(Index, NoChange_t) class CwiseNullaryOp, MatrixBase::Ones()
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
|
|
||||||
PlainObjectBase<Derived>::setOnes(NoChange_t, Index cols)
|
|
||||||
{
|
|
||||||
return setOnes(rows(), cols);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Identity:
|
// Identity:
|
||||||
|
|
||||||
/** \returns an expression of the identity matrix (not necessarily square).
|
/** \returns an expression of the identity matrix (not necessarily square).
|
||||||
@@ -960,42 +861,6 @@ template<typename Derived>
|
|||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitW()
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitW()
|
||||||
{ return Derived::Unit(3); }
|
{ return Derived::Unit(3); }
|
||||||
|
|
||||||
/** \brief Set the coefficients of \c *this to the i-th unit (basis) vector
|
|
||||||
*
|
|
||||||
* \param i index of the unique coefficient to be set to 1
|
|
||||||
*
|
|
||||||
* \only_for_vectors
|
|
||||||
*
|
|
||||||
* \sa MatrixBase::setIdentity(), class CwiseNullaryOp, MatrixBase::Unit(Index,Index)
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setUnit(Index i)
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
|
|
||||||
eigen_assert(i<size());
|
|
||||||
derived().setZero();
|
|
||||||
derived().coeffRef(i) = Scalar(1);
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief Resizes to the given \a newSize, and writes the i-th unit (basis) vector into *this.
|
|
||||||
*
|
|
||||||
* \param newSize the new size of the vector
|
|
||||||
* \param i index of the unique coefficient to be set to 1
|
|
||||||
*
|
|
||||||
* \only_for_vectors
|
|
||||||
*
|
|
||||||
* \sa MatrixBase::setIdentity(), class CwiseNullaryOp, MatrixBase::Unit(Index,Index)
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setUnit(Index newSize, Index i)
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
|
|
||||||
eigen_assert(i<newSize);
|
|
||||||
derived().resize(newSize);
|
|
||||||
return setUnit(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_CWISE_NULLARY_OP_H
|
#endif // EIGEN_CWISE_NULLARY_OP_H
|
||||||
|
|||||||
@@ -65,10 +65,10 @@ class CwiseUnaryOp : public CwiseUnaryOpImpl<UnaryOp, XprType, typename internal
|
|||||||
explicit CwiseUnaryOp(const XprType& xpr, const UnaryOp& func = UnaryOp())
|
explicit CwiseUnaryOp(const XprType& xpr, const UnaryOp& func = UnaryOp())
|
||||||
: m_xpr(xpr), m_functor(func) {}
|
: m_xpr(xpr), m_functor(func) {}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
Index rows() const EIGEN_NOEXCEPT { return m_xpr.rows(); }
|
Index rows() const { return m_xpr.rows(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
Index cols() const EIGEN_NOEXCEPT { return m_xpr.cols(); }
|
Index cols() const { return m_xpr.cols(); }
|
||||||
|
|
||||||
/** \returns the functor representing the unary operation */
|
/** \returns the functor representing the unary operation */
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
|||||||
@@ -64,26 +64,24 @@ class CwiseUnaryView : public CwiseUnaryViewImpl<ViewOp, MatrixType, typename in
|
|||||||
typedef typename internal::ref_selector<MatrixType>::non_const_type MatrixTypeNested;
|
typedef typename internal::ref_selector<MatrixType>::non_const_type MatrixTypeNested;
|
||||||
typedef typename internal::remove_all<MatrixType>::type NestedExpression;
|
typedef typename internal::remove_all<MatrixType>::type NestedExpression;
|
||||||
|
|
||||||
explicit EIGEN_DEVICE_FUNC inline CwiseUnaryView(MatrixType& mat, const ViewOp& func = ViewOp())
|
explicit inline CwiseUnaryView(MatrixType& mat, const ViewOp& func = ViewOp())
|
||||||
: m_matrix(mat), m_functor(func) {}
|
: m_matrix(mat), m_functor(func) {}
|
||||||
|
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryView)
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryView)
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
EIGEN_STRONG_INLINE Index rows() const { return m_matrix.rows(); }
|
||||||
Index rows() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
|
EIGEN_STRONG_INLINE Index cols() const { return m_matrix.cols(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
|
||||||
Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
|
|
||||||
|
|
||||||
/** \returns the functor representing unary operation */
|
/** \returns the functor representing unary operation */
|
||||||
EIGEN_DEVICE_FUNC const ViewOp& functor() const { return m_functor; }
|
const ViewOp& functor() const { return m_functor; }
|
||||||
|
|
||||||
/** \returns the nested expression */
|
/** \returns the nested expression */
|
||||||
EIGEN_DEVICE_FUNC const typename internal::remove_all<MatrixTypeNested>::type&
|
const typename internal::remove_all<MatrixTypeNested>::type&
|
||||||
nestedExpression() const { return m_matrix; }
|
nestedExpression() const { return m_matrix; }
|
||||||
|
|
||||||
/** \returns the nested expression */
|
/** \returns the nested expression */
|
||||||
EIGEN_DEVICE_FUNC typename internal::remove_reference<MatrixTypeNested>::type&
|
typename internal::remove_reference<MatrixTypeNested>::type&
|
||||||
nestedExpression() { return m_matrix; }
|
nestedExpression() { return m_matrix.const_cast_derived(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MatrixTypeNested m_matrix;
|
MatrixTypeNested m_matrix;
|
||||||
@@ -114,12 +112,12 @@ class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense>
|
|||||||
EIGEN_DEVICE_FUNC inline Scalar* data() { return &(this->coeffRef(0)); }
|
EIGEN_DEVICE_FUNC inline Scalar* data() { return &(this->coeffRef(0)); }
|
||||||
EIGEN_DEVICE_FUNC inline const Scalar* data() const { return &(this->coeff(0)); }
|
EIGEN_DEVICE_FUNC inline const Scalar* data() const { return &(this->coeff(0)); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index innerStride() const
|
EIGEN_DEVICE_FUNC inline Index innerStride() const
|
||||||
{
|
{
|
||||||
return derived().nestedExpression().innerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar);
|
return derived().nestedExpression().innerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar);
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index outerStride() const
|
EIGEN_DEVICE_FUNC inline Index outerStride() const
|
||||||
{
|
{
|
||||||
return derived().nestedExpression().outerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar);
|
return derived().nestedExpression().outerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace internal {
|
|||||||
// The index type defined by EIGEN_DEFAULT_DENSE_INDEX_TYPE must be a signed type.
|
// The index type defined by EIGEN_DEFAULT_DENSE_INDEX_TYPE must be a signed type.
|
||||||
// This dummy function simply aims at checking that at compile time.
|
// This dummy function simply aims at checking that at compile time.
|
||||||
static inline void check_DenseIndex_is_signed() {
|
static inline void check_DenseIndex_is_signed() {
|
||||||
EIGEN_STATIC_ASSERT(NumTraits<DenseIndex>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE)
|
EIGEN_STATIC_ASSERT(NumTraits<DenseIndex>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
@@ -150,18 +150,13 @@ template<typename Derived> class DenseBase
|
|||||||
* \sa SizeAtCompileTime, MaxRowsAtCompileTime, MaxColsAtCompileTime
|
* \sa SizeAtCompileTime, MaxRowsAtCompileTime, MaxColsAtCompileTime
|
||||||
*/
|
*/
|
||||||
|
|
||||||
IsVectorAtCompileTime = internal::traits<Derived>::RowsAtCompileTime == 1
|
IsVectorAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime == 1
|
||||||
|| internal::traits<Derived>::ColsAtCompileTime == 1,
|
|| internal::traits<Derived>::MaxColsAtCompileTime == 1,
|
||||||
/**< This is set to true if either the number of rows or the number of
|
/**< This is set to true if either the number of rows or the number of
|
||||||
* columns is known at compile-time to be equal to 1. Indeed, in that case,
|
* columns is known at compile-time to be equal to 1. Indeed, in that case,
|
||||||
* we are dealing with a column-vector (if there is only one column) or with
|
* we are dealing with a column-vector (if there is only one column) or with
|
||||||
* a row-vector (if there is only one row). */
|
* a row-vector (if there is only one row). */
|
||||||
|
|
||||||
NumDimensions = int(MaxSizeAtCompileTime) == 1 ? 0 : bool(IsVectorAtCompileTime) ? 1 : 2,
|
|
||||||
/**< This value is equal to Tensor::NumDimensions, i.e. 0 for scalars, 1 for vectors,
|
|
||||||
* and 2 for matrices.
|
|
||||||
*/
|
|
||||||
|
|
||||||
Flags = internal::traits<Derived>::Flags,
|
Flags = internal::traits<Derived>::Flags,
|
||||||
/**< This stores expression \ref flags flags which may or may not be inherited by new expressions
|
/**< This stores expression \ref flags flags which may or may not be inherited by new expressions
|
||||||
* constructed from this one. See the \ref flags "list of flags".
|
* constructed from this one. See the \ref flags "list of flags".
|
||||||
@@ -211,7 +206,7 @@ template<typename Derived> class DenseBase
|
|||||||
|
|
||||||
/** \returns the number of nonzero coefficients which is in practice the number
|
/** \returns the number of nonzero coefficients which is in practice the number
|
||||||
* of stored coefficients. */
|
* of stored coefficients. */
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index nonZeros() const { return size(); }
|
inline Index nonZeros() const { return size(); }
|
||||||
|
|
||||||
/** \returns the outer size.
|
/** \returns the outer size.
|
||||||
@@ -219,7 +214,7 @@ template<typename Derived> class DenseBase
|
|||||||
* \note For a vector, this returns just 1. For a matrix (non-vector), this is the major dimension
|
* \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
|
* 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. */
|
* column-major matrix, and the number of rows for a row-major matrix. */
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
Index outerSize() const
|
Index outerSize() const
|
||||||
{
|
{
|
||||||
return IsVectorAtCompileTime ? 1
|
return IsVectorAtCompileTime ? 1
|
||||||
@@ -231,7 +226,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
|
* \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
|
* 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. */
|
* column-major matrix, and the number of columns for a row-major matrix. */
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
Index innerSize() const
|
Index innerSize() const
|
||||||
{
|
{
|
||||||
return IsVectorAtCompileTime ? this->size()
|
return IsVectorAtCompileTime ? this->size()
|
||||||
@@ -266,9 +261,9 @@ template<typename Derived> class DenseBase
|
|||||||
/** \internal Represents a matrix with all coefficients equal to one another*/
|
/** \internal Represents a matrix with all coefficients equal to one another*/
|
||||||
typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,PlainObject> ConstantReturnType;
|
typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,PlainObject> ConstantReturnType;
|
||||||
/** \internal \deprecated Represents a vector with linearly spaced coefficients that allows sequential access only. */
|
/** \internal \deprecated Represents a vector with linearly spaced coefficients that allows sequential access only. */
|
||||||
EIGEN_DEPRECATED typedef CwiseNullaryOp<internal::linspaced_op<Scalar>,PlainObject> SequentialLinSpacedReturnType;
|
typedef CwiseNullaryOp<internal::linspaced_op<Scalar,PacketScalar>,PlainObject> SequentialLinSpacedReturnType;
|
||||||
/** \internal Represents a vector with linearly spaced coefficients that allows random access. */
|
/** \internal Represents a vector with linearly spaced coefficients that allows random access. */
|
||||||
typedef CwiseNullaryOp<internal::linspaced_op<Scalar>,PlainObject> RandomAccessLinSpacedReturnType;
|
typedef CwiseNullaryOp<internal::linspaced_op<Scalar,PacketScalar>,PlainObject> RandomAccessLinSpacedReturnType;
|
||||||
/** \internal the return type of MatrixBase::eigenvalues() */
|
/** \internal the return type of MatrixBase::eigenvalues() */
|
||||||
typedef Matrix<typename NumTraits<typename internal::traits<Derived>::Scalar>::Real, internal::traits<Derived>::ColsAtCompileTime, 1> EigenvaluesReturnType;
|
typedef Matrix<typename NumTraits<typename internal::traits<Derived>::Scalar>::Real, internal::traits<Derived>::ColsAtCompileTime, 1> EigenvaluesReturnType;
|
||||||
|
|
||||||
@@ -302,17 +297,17 @@ template<typename Derived> class DenseBase
|
|||||||
Derived& operator=(const ReturnByValue<OtherDerived>& func);
|
Derived& operator=(const ReturnByValue<OtherDerived>& func);
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
* Copies \a other into *this without evaluating other. \returns a reference to *this. */
|
* Copies \a other into *this without evaluating other. \returns a reference to *this.
|
||||||
|
* \deprecated */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
/** \deprecated */
|
EIGEN_DEVICE_FUNC
|
||||||
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC
|
|
||||||
Derived& lazyAssign(const DenseBase<OtherDerived>& other);
|
Derived& lazyAssign(const DenseBase<OtherDerived>& other);
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
CommaInitializer<Derived> operator<< (const Scalar& s);
|
CommaInitializer<Derived> operator<< (const Scalar& s);
|
||||||
|
|
||||||
template<unsigned int Added,unsigned int Removed>
|
|
||||||
/** \deprecated it now returns \c *this */
|
/** \deprecated it now returns \c *this */
|
||||||
|
template<unsigned int Added,unsigned int Removed>
|
||||||
EIGEN_DEPRECATED
|
EIGEN_DEPRECATED
|
||||||
const Derived& flagged() const
|
const Derived& flagged() const
|
||||||
{ return derived(); }
|
{ return derived(); }
|
||||||
@@ -324,9 +319,9 @@ template<typename Derived> class DenseBase
|
|||||||
typedef Transpose<Derived> TransposeReturnType;
|
typedef Transpose<Derived> TransposeReturnType;
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
TransposeReturnType transpose();
|
TransposeReturnType transpose();
|
||||||
typedef Transpose<const Derived> ConstTransposeReturnType;
|
typedef typename internal::add_const<Transpose<const Derived> >::type ConstTransposeReturnType;
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const ConstTransposeReturnType transpose() const;
|
ConstTransposeReturnType transpose() const;
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
void transposeInPlace();
|
void transposeInPlace();
|
||||||
|
|
||||||
@@ -337,13 +332,12 @@ template<typename Derived> class DenseBase
|
|||||||
EIGEN_DEVICE_FUNC static const ConstantReturnType
|
EIGEN_DEVICE_FUNC static const ConstantReturnType
|
||||||
Constant(const Scalar& value);
|
Constant(const Scalar& value);
|
||||||
|
|
||||||
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType
|
EIGEN_DEVICE_FUNC static const SequentialLinSpacedReturnType
|
||||||
LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high);
|
LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high);
|
||||||
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType
|
|
||||||
LinSpaced(Sequential_t, const Scalar& low, const Scalar& high);
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType
|
EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType
|
||||||
LinSpaced(Index size, const Scalar& low, const Scalar& high);
|
LinSpaced(Index size, const Scalar& low, const Scalar& high);
|
||||||
|
EIGEN_DEVICE_FUNC static const SequentialLinSpacedReturnType
|
||||||
|
LinSpaced(Sequential_t, const Scalar& low, const Scalar& high);
|
||||||
EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType
|
EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType
|
||||||
LinSpaced(const Scalar& low, const Scalar& high);
|
LinSpaced(const Scalar& low, const Scalar& high);
|
||||||
|
|
||||||
@@ -401,7 +395,7 @@ template<typename Derived> class DenseBase
|
|||||||
* Notice that in the case of a plain matrix or vector (not an expression) this function just returns
|
* 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.
|
* a const reference, in order to avoid a useless copy.
|
||||||
*
|
*
|
||||||
* \warning Be careful with eval() and the auto C++ keyword, as detailed in this \link TopicPitfalls_auto_keyword page \endlink.
|
* \warning Be carefull with eval() and the auto C++ keyword, as detailed in this \link TopicPitfalls_auto_keyword page \endlink.
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
EIGEN_STRONG_INLINE EvalReturnType eval() const
|
EIGEN_STRONG_INLINE EvalReturnType eval() const
|
||||||
@@ -416,7 +410,7 @@ template<typename Derived> class DenseBase
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
void swap(const DenseBase<OtherDerived>& other)
|
void swap(const DenseBase<OtherDerived>& other)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT(!OtherDerived::IsPlainObjectBase,THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
|
EIGEN_STATIC_ASSERT(!OtherDerived::IsPlainObjectBase,THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
|
||||||
@@ -428,7 +422,7 @@ template<typename Derived> class DenseBase
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
void swap(PlainObjectBase<OtherDerived>& other)
|
void swap(PlainObjectBase<OtherDerived>& other)
|
||||||
{
|
{
|
||||||
eigen_assert(rows()==other.rows() && cols()==other.cols());
|
eigen_assert(rows()==other.rows() && cols()==other.cols());
|
||||||
@@ -449,58 +443,18 @@ template<typename Derived> class DenseBase
|
|||||||
|
|
||||||
EIGEN_DEVICE_FUNC Scalar prod() const;
|
EIGEN_DEVICE_FUNC Scalar prod() const;
|
||||||
|
|
||||||
template<int NaNPropagation>
|
|
||||||
EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar minCoeff() const;
|
EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar minCoeff() const;
|
||||||
template<int NaNPropagation>
|
|
||||||
EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar maxCoeff() const;
|
EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar maxCoeff() const;
|
||||||
|
|
||||||
|
template<typename IndexType> EIGEN_DEVICE_FUNC
|
||||||
// By default, the fastest version with undefined NaN propagation semantics is
|
|
||||||
// used.
|
|
||||||
// TODO(rmlarsen): Replace with default template argument when we move to
|
|
||||||
// c++11 or beyond.
|
|
||||||
EIGEN_DEVICE_FUNC inline typename internal::traits<Derived>::Scalar minCoeff() const {
|
|
||||||
return minCoeff<PropagateFast>();
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC inline typename internal::traits<Derived>::Scalar maxCoeff() const {
|
|
||||||
return maxCoeff<PropagateFast>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int NaNPropagation, typename IndexType>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
typename internal::traits<Derived>::Scalar minCoeff(IndexType* row, IndexType* col) const;
|
typename internal::traits<Derived>::Scalar minCoeff(IndexType* row, IndexType* col) const;
|
||||||
template<int NaNPropagation, typename IndexType>
|
template<typename IndexType> EIGEN_DEVICE_FUNC
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
typename internal::traits<Derived>::Scalar maxCoeff(IndexType* row, IndexType* col) const;
|
typename internal::traits<Derived>::Scalar maxCoeff(IndexType* row, IndexType* col) const;
|
||||||
template<int NaNPropagation, typename IndexType>
|
template<typename IndexType> EIGEN_DEVICE_FUNC
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
typename internal::traits<Derived>::Scalar minCoeff(IndexType* index) const;
|
typename internal::traits<Derived>::Scalar minCoeff(IndexType* index) const;
|
||||||
template<int NaNPropagation, typename IndexType>
|
template<typename IndexType> EIGEN_DEVICE_FUNC
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
typename internal::traits<Derived>::Scalar maxCoeff(IndexType* index) const;
|
typename internal::traits<Derived>::Scalar maxCoeff(IndexType* index) const;
|
||||||
|
|
||||||
// TODO(rmlarsen): Replace these methods with a default template argument.
|
|
||||||
template<typename IndexType>
|
|
||||||
EIGEN_DEVICE_FUNC inline
|
|
||||||
typename internal::traits<Derived>::Scalar minCoeff(IndexType* row, IndexType* col) const {
|
|
||||||
return minCoeff<PropagateFast>(row, col);
|
|
||||||
}
|
|
||||||
template<typename IndexType>
|
|
||||||
EIGEN_DEVICE_FUNC inline
|
|
||||||
typename internal::traits<Derived>::Scalar maxCoeff(IndexType* row, IndexType* col) const {
|
|
||||||
return maxCoeff<PropagateFast>(row, col);
|
|
||||||
}
|
|
||||||
template<typename IndexType>
|
|
||||||
EIGEN_DEVICE_FUNC inline
|
|
||||||
typename internal::traits<Derived>::Scalar minCoeff(IndexType* index) const {
|
|
||||||
return minCoeff<PropagateFast>(index);
|
|
||||||
}
|
|
||||||
template<typename IndexType>
|
|
||||||
EIGEN_DEVICE_FUNC inline
|
|
||||||
typename internal::traits<Derived>::Scalar maxCoeff(IndexType* index) const {
|
|
||||||
return maxCoeff<PropagateFast>(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename BinaryOp>
|
template<typename BinaryOp>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
Scalar redux(const BinaryOp& func) const;
|
Scalar redux(const BinaryOp& func) const;
|
||||||
@@ -539,7 +493,7 @@ template<typename Derived> class DenseBase
|
|||||||
typedef VectorwiseOp<Derived, Vertical> ColwiseReturnType;
|
typedef VectorwiseOp<Derived, Vertical> ColwiseReturnType;
|
||||||
typedef const VectorwiseOp<const Derived, Vertical> ConstColwiseReturnType;
|
typedef const VectorwiseOp<const Derived, Vertical> ConstColwiseReturnType;
|
||||||
|
|
||||||
/** \returns a VectorwiseOp wrapper of *this for broadcasting and partial reductions
|
/** \returns a VectorwiseOp wrapper of *this providing additional partial reduction operations
|
||||||
*
|
*
|
||||||
* Example: \include MatrixBase_rowwise.cpp
|
* Example: \include MatrixBase_rowwise.cpp
|
||||||
* Output: \verbinclude MatrixBase_rowwise.out
|
* Output: \verbinclude MatrixBase_rowwise.out
|
||||||
@@ -552,7 +506,7 @@ template<typename Derived> class DenseBase
|
|||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC RowwiseReturnType rowwise();
|
EIGEN_DEVICE_FUNC RowwiseReturnType rowwise();
|
||||||
|
|
||||||
/** \returns a VectorwiseOp wrapper of *this broadcasting and partial reductions
|
/** \returns a VectorwiseOp wrapper of *this providing additional partial reduction operations
|
||||||
*
|
*
|
||||||
* Example: \include MatrixBase_colwise.cpp
|
* Example: \include MatrixBase_colwise.cpp
|
||||||
* Output: \verbinclude MatrixBase_colwise.out
|
* Output: \verbinclude MatrixBase_colwise.out
|
||||||
@@ -570,16 +524,16 @@ template<typename Derived> class DenseBase
|
|||||||
static const RandomReturnType Random();
|
static const RandomReturnType Random();
|
||||||
|
|
||||||
template<typename ThenDerived,typename ElseDerived>
|
template<typename ThenDerived,typename ElseDerived>
|
||||||
inline EIGEN_DEVICE_FUNC const Select<Derived,ThenDerived,ElseDerived>
|
const Select<Derived,ThenDerived,ElseDerived>
|
||||||
select(const DenseBase<ThenDerived>& thenMatrix,
|
select(const DenseBase<ThenDerived>& thenMatrix,
|
||||||
const DenseBase<ElseDerived>& elseMatrix) const;
|
const DenseBase<ElseDerived>& elseMatrix) const;
|
||||||
|
|
||||||
template<typename ThenDerived>
|
template<typename ThenDerived>
|
||||||
inline EIGEN_DEVICE_FUNC const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
|
inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
|
||||||
select(const DenseBase<ThenDerived>& thenMatrix, const typename ThenDerived::Scalar& elseScalar) const;
|
select(const DenseBase<ThenDerived>& thenMatrix, const typename ThenDerived::Scalar& elseScalar) const;
|
||||||
|
|
||||||
template<typename ElseDerived>
|
template<typename ElseDerived>
|
||||||
inline EIGEN_DEVICE_FUNC const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
|
inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
|
||||||
select(const typename ElseDerived::Scalar& thenScalar, const DenseBase<ElseDerived>& elseMatrix) const;
|
select(const typename ElseDerived::Scalar& thenScalar, const DenseBase<ElseDerived>& elseMatrix) const;
|
||||||
|
|
||||||
template<int p> RealScalar lpNorm() const;
|
template<int p> RealScalar lpNorm() const;
|
||||||
@@ -613,59 +567,16 @@ template<typename Derived> class DenseBase
|
|||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC void reverseInPlace();
|
EIGEN_DEVICE_FUNC void reverseInPlace();
|
||||||
|
|
||||||
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
/** STL-like <a href="https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator">RandomAccessIterator</a>
|
|
||||||
* iterator type as returned by the begin() and end() methods.
|
|
||||||
*/
|
|
||||||
typedef random_access_iterator_type iterator;
|
|
||||||
/** This is the const version of iterator (aka read-only) */
|
|
||||||
typedef random_access_iterator_type const_iterator;
|
|
||||||
#else
|
|
||||||
typedef typename internal::conditional< (Flags&DirectAccessBit)==DirectAccessBit,
|
|
||||||
internal::pointer_based_stl_iterator<Derived>,
|
|
||||||
internal::generic_randaccess_stl_iterator<Derived>
|
|
||||||
>::type iterator_type;
|
|
||||||
|
|
||||||
typedef typename internal::conditional< (Flags&DirectAccessBit)==DirectAccessBit,
|
|
||||||
internal::pointer_based_stl_iterator<const Derived>,
|
|
||||||
internal::generic_randaccess_stl_iterator<const Derived>
|
|
||||||
>::type const_iterator_type;
|
|
||||||
|
|
||||||
// Stl-style iterators are supported only for vectors.
|
|
||||||
|
|
||||||
typedef typename internal::conditional< IsVectorAtCompileTime,
|
|
||||||
iterator_type,
|
|
||||||
void
|
|
||||||
>::type iterator;
|
|
||||||
|
|
||||||
typedef typename internal::conditional< IsVectorAtCompileTime,
|
|
||||||
const_iterator_type,
|
|
||||||
void
|
|
||||||
>::type const_iterator;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline iterator begin();
|
|
||||||
inline const_iterator begin() const;
|
|
||||||
inline const_iterator cbegin() const;
|
|
||||||
inline iterator end();
|
|
||||||
inline const_iterator end() const;
|
|
||||||
inline const_iterator cend() const;
|
|
||||||
|
|
||||||
#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::DenseBase
|
#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::DenseBase
|
||||||
#define EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
|
#define EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
|
||||||
#define EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(COND)
|
#define EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(COND)
|
||||||
#define EIGEN_DOC_UNARY_ADDONS(X,Y)
|
|
||||||
# include "../plugins/CommonCwiseUnaryOps.h"
|
|
||||||
# include "../plugins/BlockMethods.h"
|
# include "../plugins/BlockMethods.h"
|
||||||
# include "../plugins/IndexedViewMethods.h"
|
|
||||||
# include "../plugins/ReshapedMethods.h"
|
|
||||||
# ifdef EIGEN_DENSEBASE_PLUGIN
|
# ifdef EIGEN_DENSEBASE_PLUGIN
|
||||||
# include EIGEN_DENSEBASE_PLUGIN
|
# include EIGEN_DENSEBASE_PLUGIN
|
||||||
# endif
|
# endif
|
||||||
#undef EIGEN_CURRENT_STORAGE_BASE_CLASS
|
#undef EIGEN_CURRENT_STORAGE_BASE_CLASS
|
||||||
#undef EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
|
#undef EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
|
||||||
#undef EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF
|
#undef EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF
|
||||||
#undef EIGEN_DOC_UNARY_ADDONS
|
|
||||||
|
|
||||||
// disable the use of evalTo for dense objects with a nice compilation error
|
// disable the use of evalTo for dense objects with a nice compilation error
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
|
|||||||
@@ -22,8 +22,7 @@ template<typename T> struct add_const_on_value_type_if_arithmetic
|
|||||||
/** \brief Base class providing read-only coefficient access to matrices and arrays.
|
/** \brief Base class providing read-only coefficient access to matrices and arrays.
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
* \tparam Derived Type of the derived class
|
* \tparam Derived Type of the derived class
|
||||||
*
|
* \tparam #ReadOnlyAccessors Constant indicating read-only access
|
||||||
* \note #ReadOnlyAccessors Constant indicating read-only access
|
|
||||||
*
|
*
|
||||||
* This class defines the \c operator() \c const function and friends, which can be used to read specific
|
* This class defines the \c operator() \c const function and friends, which can be used to read specific
|
||||||
* entries of a matrix or array.
|
* entries of a matrix or array.
|
||||||
@@ -289,8 +288,7 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
|||||||
/** \brief Base class providing read/write coefficient access to matrices and arrays.
|
/** \brief Base class providing read/write coefficient access to matrices and arrays.
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
* \tparam Derived Type of the derived class
|
* \tparam Derived Type of the derived class
|
||||||
*
|
* \tparam #WriteAccessors Constant indicating read/write access
|
||||||
* \note #WriteAccessors Constant indicating read/write access
|
|
||||||
*
|
*
|
||||||
* This class defines the non-const \c operator() function and friends, which can be used to write specific
|
* This class defines the non-const \c operator() function and friends, which can be used to write specific
|
||||||
* entries of a matrix or array. This class inherits DenseCoeffsBase<Derived, ReadOnlyAccessors> which
|
* entries of a matrix or array. This class inherits DenseCoeffsBase<Derived, ReadOnlyAccessors> which
|
||||||
@@ -468,8 +466,7 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
|||||||
/** \brief Base class providing direct read-only coefficient access to matrices and arrays.
|
/** \brief Base class providing direct read-only coefficient access to matrices and arrays.
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
* \tparam Derived Type of the derived class
|
* \tparam Derived Type of the derived class
|
||||||
*
|
* \tparam #DirectAccessors Constant indicating direct access
|
||||||
* \note #DirectAccessors Constant indicating direct access
|
|
||||||
*
|
*
|
||||||
* This class defines functions to work with strides which can be used to access entries directly. This class
|
* This class defines functions to work with strides which can be used to access entries directly. This class
|
||||||
* inherits DenseCoeffsBase<Derived, ReadOnlyAccessors> which defines functions to access entries read-only using
|
* inherits DenseCoeffsBase<Derived, ReadOnlyAccessors> which defines functions to access entries read-only using
|
||||||
@@ -495,7 +492,7 @@ class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived
|
|||||||
*
|
*
|
||||||
* \sa outerStride(), rowStride(), colStride()
|
* \sa outerStride(), rowStride(), colStride()
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index innerStride() const
|
inline Index innerStride() const
|
||||||
{
|
{
|
||||||
return derived().innerStride();
|
return derived().innerStride();
|
||||||
@@ -506,14 +503,14 @@ class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived
|
|||||||
*
|
*
|
||||||
* \sa innerStride(), rowStride(), colStride()
|
* \sa innerStride(), rowStride(), colStride()
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index outerStride() const
|
inline Index outerStride() const
|
||||||
{
|
{
|
||||||
return derived().outerStride();
|
return derived().outerStride();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME shall we remove it ?
|
// FIXME shall we remove it ?
|
||||||
EIGEN_CONSTEXPR inline Index stride() const
|
inline Index stride() const
|
||||||
{
|
{
|
||||||
return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
|
return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
|
||||||
}
|
}
|
||||||
@@ -522,7 +519,7 @@ class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived
|
|||||||
*
|
*
|
||||||
* \sa innerStride(), outerStride(), colStride()
|
* \sa innerStride(), outerStride(), colStride()
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index rowStride() const
|
inline Index rowStride() const
|
||||||
{
|
{
|
||||||
return Derived::IsRowMajor ? outerStride() : innerStride();
|
return Derived::IsRowMajor ? outerStride() : innerStride();
|
||||||
@@ -532,7 +529,7 @@ class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived
|
|||||||
*
|
*
|
||||||
* \sa innerStride(), outerStride(), rowStride()
|
* \sa innerStride(), outerStride(), rowStride()
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index colStride() const
|
inline Index colStride() const
|
||||||
{
|
{
|
||||||
return Derived::IsRowMajor ? innerStride() : outerStride();
|
return Derived::IsRowMajor ? innerStride() : outerStride();
|
||||||
@@ -542,8 +539,7 @@ class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived
|
|||||||
/** \brief Base class providing direct read/write coefficient access to matrices and arrays.
|
/** \brief Base class providing direct read/write coefficient access to matrices and arrays.
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
* \tparam Derived Type of the derived class
|
* \tparam Derived Type of the derived class
|
||||||
*
|
* \tparam #DirectWriteAccessors Constant indicating direct access
|
||||||
* \note #DirectWriteAccessors Constant indicating direct access
|
|
||||||
*
|
*
|
||||||
* This class defines functions to work with strides which can be used to access entries directly. This class
|
* This class defines functions to work with strides which can be used to access entries directly. This class
|
||||||
* inherits DenseCoeffsBase<Derived, WriteAccessors> which defines functions to access entries read/write using
|
* inherits DenseCoeffsBase<Derived, WriteAccessors> which defines functions to access entries read/write using
|
||||||
@@ -570,8 +566,8 @@ class DenseCoeffsBase<Derived, DirectWriteAccessors>
|
|||||||
*
|
*
|
||||||
* \sa outerStride(), rowStride(), colStride()
|
* \sa outerStride(), rowStride(), colStride()
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index innerStride() const EIGEN_NOEXCEPT
|
inline Index innerStride() const
|
||||||
{
|
{
|
||||||
return derived().innerStride();
|
return derived().innerStride();
|
||||||
}
|
}
|
||||||
@@ -581,14 +577,14 @@ class DenseCoeffsBase<Derived, DirectWriteAccessors>
|
|||||||
*
|
*
|
||||||
* \sa innerStride(), rowStride(), colStride()
|
* \sa innerStride(), rowStride(), colStride()
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index outerStride() const EIGEN_NOEXCEPT
|
inline Index outerStride() const
|
||||||
{
|
{
|
||||||
return derived().outerStride();
|
return derived().outerStride();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME shall we remove it ?
|
// FIXME shall we remove it ?
|
||||||
EIGEN_CONSTEXPR inline Index stride() const EIGEN_NOEXCEPT
|
inline Index stride() const
|
||||||
{
|
{
|
||||||
return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
|
return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
|
||||||
}
|
}
|
||||||
@@ -597,8 +593,8 @@ class DenseCoeffsBase<Derived, DirectWriteAccessors>
|
|||||||
*
|
*
|
||||||
* \sa innerStride(), outerStride(), colStride()
|
* \sa innerStride(), outerStride(), colStride()
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index rowStride() const EIGEN_NOEXCEPT
|
inline Index rowStride() const
|
||||||
{
|
{
|
||||||
return Derived::IsRowMajor ? outerStride() : innerStride();
|
return Derived::IsRowMajor ? outerStride() : innerStride();
|
||||||
}
|
}
|
||||||
@@ -607,8 +603,8 @@ class DenseCoeffsBase<Derived, DirectWriteAccessors>
|
|||||||
*
|
*
|
||||||
* \sa innerStride(), outerStride(), rowStride()
|
* \sa innerStride(), outerStride(), rowStride()
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index colStride() const EIGEN_NOEXCEPT
|
inline Index colStride() const
|
||||||
{
|
{
|
||||||
return Derived::IsRowMajor ? innerStride() : outerStride();
|
return Derived::IsRowMajor ? innerStride() : outerStride();
|
||||||
}
|
}
|
||||||
@@ -619,7 +615,7 @@ namespace internal {
|
|||||||
template<int Alignment, typename Derived, bool JustReturnZero>
|
template<int Alignment, typename Derived, bool JustReturnZero>
|
||||||
struct first_aligned_impl
|
struct first_aligned_impl
|
||||||
{
|
{
|
||||||
static EIGEN_CONSTEXPR inline Index run(const Derived&) EIGEN_NOEXCEPT
|
static inline Index run(const Derived&)
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ struct plain_array
|
|||||||
#if defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT)
|
#if defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT)
|
||||||
#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask)
|
#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask)
|
||||||
#elif EIGEN_GNUC_AT_LEAST(4,7)
|
#elif EIGEN_GNUC_AT_LEAST(4,7)
|
||||||
// GCC 4.7 is too aggressive in its optimizations and remove the alignment test based on the fact the array is declared to be aligned.
|
// GCC 4.7 is too aggressive in its optimizations and remove the alignement test based on the fact the array is declared to be aligned.
|
||||||
// See this bug report: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53900
|
// See this bug report: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53900
|
||||||
// Hiding the origin of the array pointer behind a function argument seems to do the trick even if the function is inlined:
|
// Hiding the origin of the array pointer behind a function argument seems to do the trick even if the function is inlined:
|
||||||
template<typename PtrType>
|
template<typename PtrType>
|
||||||
@@ -163,30 +163,6 @@ struct plain_array<T, 0, MatrixOrArrayOptions, Alignment>
|
|||||||
EIGEN_DEVICE_FUNC plain_array(constructor_without_unaligned_array_assert) {}
|
EIGEN_DEVICE_FUNC plain_array(constructor_without_unaligned_array_assert) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct plain_array_helper {
|
|
||||||
template<typename T, int Size, int MatrixOrArrayOptions, int Alignment>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
static void copy(const plain_array<T, Size, MatrixOrArrayOptions, Alignment>& src, const Eigen::Index size,
|
|
||||||
plain_array<T, Size, MatrixOrArrayOptions, Alignment>& dst) {
|
|
||||||
smart_copy(src.array, src.array + size, dst.array);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, int Size, int MatrixOrArrayOptions, int Alignment>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
static void swap(plain_array<T, Size, MatrixOrArrayOptions, Alignment>& a, const Eigen::Index a_size,
|
|
||||||
plain_array<T, Size, MatrixOrArrayOptions, Alignment>& b, const Eigen::Index b_size) {
|
|
||||||
if (a_size < b_size) {
|
|
||||||
std::swap_ranges(b.array, b.array + a_size, a.array);
|
|
||||||
smart_move(b.array + a_size, b.array + b_size, a.array + a_size);
|
|
||||||
} else if (a_size > b_size) {
|
|
||||||
std::swap_ranges(a.array, a.array + b_size, b.array);
|
|
||||||
smart_move(a.array + b_size, a.array + a_size, b.array + b_size);
|
|
||||||
} else {
|
|
||||||
std::swap_ranges(a.array, a.array + a_size, b.array);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
@@ -214,41 +190,16 @@ template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseSt
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
|
explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||||
: m_data(internal::constructor_without_unaligned_array_assert()) {}
|
: m_data(internal::constructor_without_unaligned_array_assert()) {}
|
||||||
#if !EIGEN_HAS_CXX11 || defined(EIGEN_DENSE_STORAGE_CTOR_PLUGIN)
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
DenseStorage(const DenseStorage& other) : m_data(other.m_data) {
|
DenseStorage(const DenseStorage& other) : m_data(other.m_data) {
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size)
|
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size)
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage&) = default;
|
|
||||||
#endif
|
|
||||||
#if !EIGEN_HAS_CXX11
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
DenseStorage& operator=(const DenseStorage& other)
|
DenseStorage& operator=(const DenseStorage& other)
|
||||||
{
|
{
|
||||||
if (this != &other) m_data = other.m_data;
|
if (this != &other) m_data = other.m_data;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage&) = default;
|
|
||||||
#endif
|
|
||||||
#if EIGEN_HAS_RVALUE_REFERENCES
|
|
||||||
#if !EIGEN_HAS_CXX11
|
|
||||||
EIGEN_DEVICE_FUNC DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT
|
|
||||||
: m_data(std::move(other.m_data))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
|
|
||||||
{
|
|
||||||
if (this != &other)
|
|
||||||
m_data = std::move(other.m_data);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
EIGEN_DEVICE_FUNC DenseStorage(DenseStorage&&) = default;
|
|
||||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(DenseStorage&&) = default;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) {
|
EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) {
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
|
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
|
||||||
eigen_internal_assert(size==rows*cols && rows==_Rows && cols==_Cols);
|
eigen_internal_assert(size==rows*cols && rows==_Rows && cols==_Cols);
|
||||||
@@ -256,11 +207,9 @@ template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseSt
|
|||||||
EIGEN_UNUSED_VARIABLE(rows);
|
EIGEN_UNUSED_VARIABLE(rows);
|
||||||
EIGEN_UNUSED_VARIABLE(cols);
|
EIGEN_UNUSED_VARIABLE(cols);
|
||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
|
EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); }
|
||||||
numext::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 static EIGEN_CONSTEXPR Index rows(void) EIGEN_NOEXCEPT {return _Rows;}
|
|
||||||
EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index cols(void) EIGEN_NOEXCEPT {return _Cols;}
|
|
||||||
EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {}
|
EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {}
|
||||||
EIGEN_DEVICE_FUNC void resize(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 const T *data() const { return m_data.array; }
|
||||||
@@ -277,8 +226,8 @@ template<typename T, int _Rows, int _Cols, int _Options> class DenseStorage<T, 0
|
|||||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage&) { return *this; }
|
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage&) { return *this; }
|
||||||
EIGEN_DEVICE_FUNC DenseStorage(Index,Index,Index) {}
|
EIGEN_DEVICE_FUNC DenseStorage(Index,Index,Index) {}
|
||||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& ) {}
|
EIGEN_DEVICE_FUNC void swap(DenseStorage& ) {}
|
||||||
EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index rows(void) EIGEN_NOEXCEPT {return _Rows;}
|
EIGEN_DEVICE_FUNC static Index rows(void) {return _Rows;}
|
||||||
EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index cols(void) EIGEN_NOEXCEPT {return _Cols;}
|
EIGEN_DEVICE_FUNC static Index cols(void) {return _Cols;}
|
||||||
EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {}
|
EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {}
|
||||||
EIGEN_DEVICE_FUNC void resize(Index,Index,Index) {}
|
EIGEN_DEVICE_FUNC void resize(Index,Index,Index) {}
|
||||||
EIGEN_DEVICE_FUNC const T *data() const { return 0; }
|
EIGEN_DEVICE_FUNC const T *data() const { return 0; }
|
||||||
@@ -305,28 +254,20 @@ template<typename T, int Size, int _Options> class DenseStorage<T, Size, Dynamic
|
|||||||
EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0), m_cols(0) {}
|
EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0), m_cols(0) {}
|
||||||
EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
|
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) {}
|
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {}
|
||||||
EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
|
EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows), m_cols(other.m_cols) {}
|
||||||
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(other.m_rows), m_cols(other.m_cols)
|
|
||||||
{
|
|
||||||
internal::plain_array_helper::copy(other.m_data, m_rows * m_cols, m_data);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
||||||
{
|
{
|
||||||
if (this != &other)
|
if (this != &other)
|
||||||
{
|
{
|
||||||
|
m_data = other.m_data;
|
||||||
m_rows = other.m_rows;
|
m_rows = other.m_rows;
|
||||||
m_cols = other.m_cols;
|
m_cols = other.m_cols;
|
||||||
internal::plain_array_helper::copy(other.m_data, m_rows * m_cols, m_data);
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index cols) : m_rows(rows), m_cols(cols) {}
|
EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index cols) : m_rows(rows), m_cols(cols) {}
|
||||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& other)
|
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); }
|
||||||
internal::plain_array_helper::swap(m_data, m_rows * m_cols, other.m_data, other.m_rows * other.m_cols);
|
|
||||||
numext::swap(m_rows,other.m_rows);
|
|
||||||
numext::swap(m_cols,other.m_cols);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC Index rows() const {return m_rows;}
|
EIGEN_DEVICE_FUNC Index rows() const {return m_rows;}
|
||||||
EIGEN_DEVICE_FUNC Index cols() const {return m_cols;}
|
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 conservativeResize(Index, Index rows, Index cols) { m_rows = rows; m_cols = cols; }
|
||||||
@@ -344,29 +285,20 @@ template<typename T, int Size, int _Cols, int _Options> class DenseStorage<T, Si
|
|||||||
EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0) {}
|
EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0) {}
|
||||||
EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
|
EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||||
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {}
|
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {}
|
||||||
EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
|
EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows) {}
|
||||||
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(other.m_rows)
|
|
||||||
{
|
|
||||||
internal::plain_array_helper::copy(other.m_data, m_rows * _Cols, m_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
||||||
{
|
{
|
||||||
if (this != &other)
|
if (this != &other)
|
||||||
{
|
{
|
||||||
|
m_data = other.m_data;
|
||||||
m_rows = other.m_rows;
|
m_rows = other.m_rows;
|
||||||
internal::plain_array_helper::copy(other.m_data, m_rows * _Cols, m_data);
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index) : m_rows(rows) {}
|
EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index) : m_rows(rows) {}
|
||||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& other)
|
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;}
|
||||||
internal::plain_array_helper::swap(m_data, m_rows * _Cols, other.m_data, other.m_rows * _Cols);
|
EIGEN_DEVICE_FUNC Index cols(void) const {return _Cols;}
|
||||||
numext::swap(m_rows, other.m_rows);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC Index rows(void) const EIGEN_NOEXCEPT {return m_rows;}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols(void) const EIGEN_NOEXCEPT {return _Cols;}
|
|
||||||
EIGEN_DEVICE_FUNC void conservativeResize(Index, Index rows, Index) { m_rows = rows; }
|
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 void resize(Index, Index rows, Index) { m_rows = rows; }
|
||||||
EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
|
EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
|
||||||
@@ -382,29 +314,22 @@ template<typename T, int Size, int _Rows, int _Options> class DenseStorage<T, Si
|
|||||||
EIGEN_DEVICE_FUNC DenseStorage() : m_cols(0) {}
|
EIGEN_DEVICE_FUNC DenseStorage() : m_cols(0) {}
|
||||||
EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
|
EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||||
: m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {}
|
: m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {}
|
||||||
EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
|
EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_cols(other.m_cols) {}
|
||||||
: m_data(internal::constructor_without_unaligned_array_assert()), m_cols(other.m_cols)
|
|
||||||
{
|
|
||||||
internal::plain_array_helper::copy(other.m_data, _Rows * m_cols, m_data);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
||||||
{
|
{
|
||||||
if (this != &other)
|
if (this != &other)
|
||||||
{
|
{
|
||||||
|
m_data = other.m_data;
|
||||||
m_cols = other.m_cols;
|
m_cols = other.m_cols;
|
||||||
internal::plain_array_helper::copy(other.m_data, _Rows * m_cols, m_data);
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC DenseStorage(Index, Index, Index cols) : m_cols(cols) {}
|
EIGEN_DEVICE_FUNC DenseStorage(Index, Index, Index cols) : m_cols(cols) {}
|
||||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
|
EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
|
||||||
internal::plain_array_helper::swap(m_data, _Rows * m_cols, other.m_data, _Rows * other.m_cols);
|
EIGEN_DEVICE_FUNC Index rows(void) const {return _Rows;}
|
||||||
numext::swap(m_cols, other.m_cols);
|
EIGEN_DEVICE_FUNC Index cols(void) const {return m_cols;}
|
||||||
}
|
void conservativeResize(Index, Index, Index cols) { m_cols = cols; }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows(void) const EIGEN_NOEXCEPT {return _Rows;}
|
void resize(Index, Index, Index cols) { m_cols = cols; }
|
||||||
EIGEN_DEVICE_FUNC Index cols(void) const EIGEN_NOEXCEPT {return m_cols;}
|
|
||||||
EIGEN_DEVICE_FUNC void conservativeResize(Index, Index, Index cols) { m_cols = cols; }
|
|
||||||
EIGEN_DEVICE_FUNC void resize(Index, Index, Index cols) { m_cols = cols; }
|
|
||||||
EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
|
EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
|
||||||
EIGEN_DEVICE_FUNC T *data() { return m_data.array; }
|
EIGEN_DEVICE_FUNC T *data() { return m_data.array; }
|
||||||
};
|
};
|
||||||
@@ -456,21 +381,18 @@ template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynam
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
|
DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
|
||||||
{
|
{
|
||||||
numext::swap(m_data, other.m_data);
|
using std::swap;
|
||||||
numext::swap(m_rows, other.m_rows);
|
swap(m_data, other.m_data);
|
||||||
numext::swap(m_cols, other.m_cols);
|
swap(m_rows, other.m_rows);
|
||||||
|
swap(m_cols, other.m_cols);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols); }
|
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)
|
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); }
|
||||||
numext::swap(m_data,other.m_data);
|
EIGEN_DEVICE_FUNC Index rows(void) const {return m_rows;}
|
||||||
numext::swap(m_rows,other.m_rows);
|
EIGEN_DEVICE_FUNC Index cols(void) const {return m_cols;}
|
||||||
numext::swap(m_cols,other.m_cols);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC Index rows(void) const EIGEN_NOEXCEPT {return m_rows;}
|
|
||||||
EIGEN_DEVICE_FUNC Index cols(void) const EIGEN_NOEXCEPT {return m_cols;}
|
|
||||||
void conservativeResize(Index size, Index rows, Index 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_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*m_cols);
|
||||||
@@ -537,18 +459,16 @@ template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Ro
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
|
DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
|
||||||
{
|
{
|
||||||
numext::swap(m_data, other.m_data);
|
using std::swap;
|
||||||
numext::swap(m_cols, other.m_cols);
|
swap(m_data, other.m_data);
|
||||||
|
swap(m_cols, other.m_cols);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); }
|
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) {
|
EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
|
||||||
numext::swap(m_data,other.m_data);
|
EIGEN_DEVICE_FUNC static Index rows(void) {return _Rows;}
|
||||||
numext::swap(m_cols,other.m_cols);
|
EIGEN_DEVICE_FUNC Index cols(void) const {return m_cols;}
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index rows(void) EIGEN_NOEXCEPT {return _Rows;}
|
|
||||||
EIGEN_DEVICE_FUNC Index cols(void) const EIGEN_NOEXCEPT {return m_cols;}
|
|
||||||
EIGEN_DEVICE_FUNC void conservativeResize(Index size, Index, Index 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_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, _Rows*m_cols);
|
||||||
@@ -613,18 +533,16 @@ template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dyn
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
|
DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
|
||||||
{
|
{
|
||||||
numext::swap(m_data, other.m_data);
|
using std::swap;
|
||||||
numext::swap(m_rows, other.m_rows);
|
swap(m_data, other.m_data);
|
||||||
|
swap(m_rows, other.m_rows);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); }
|
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) {
|
EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
|
||||||
numext::swap(m_data,other.m_data);
|
EIGEN_DEVICE_FUNC Index rows(void) const {return m_rows;}
|
||||||
numext::swap(m_rows,other.m_rows);
|
EIGEN_DEVICE_FUNC static Index cols(void) {return _Cols;}
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC Index rows(void) const EIGEN_NOEXCEPT {return m_rows;}
|
|
||||||
EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index cols(void) {return _Cols;}
|
|
||||||
void conservativeResize(Index size, Index rows, Index)
|
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_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*_Cols);
|
||||||
|
|||||||
@@ -84,16 +84,20 @@ template<typename MatrixType, int _DiagIndex> class Diagonal
|
|||||||
: numext::mini<Index>(m_matrix.rows(),m_matrix.cols()-m_index.value());
|
: numext::mini<Index>(m_matrix.rows(),m_matrix.cols()-m_index.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index cols() const EIGEN_NOEXCEPT { return 1; }
|
inline Index cols() const { return 1; }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index innerStride() const EIGEN_NOEXCEPT {
|
inline Index innerStride() const
|
||||||
|
{
|
||||||
return m_matrix.outerStride() + 1;
|
return m_matrix.outerStride() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index outerStride() const EIGEN_NOEXCEPT { return 0; }
|
inline Index outerStride() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
typedef typename internal::conditional<
|
typedef typename internal::conditional<
|
||||||
internal::is_lvalue<MatrixType>::value,
|
internal::is_lvalue<MatrixType>::value,
|
||||||
@@ -163,12 +167,12 @@ template<typename MatrixType, int _DiagIndex> class Diagonal
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// some compilers may fail to optimize std::max etc in case of compile-time constants...
|
// some compilers may fail to optimize std::max etc in case of compile-time constants...
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
Index absDiagIndex() const EIGEN_NOEXCEPT { return m_index.value()>0 ? m_index.value() : -m_index.value(); }
|
EIGEN_STRONG_INLINE Index absDiagIndex() const { return m_index.value()>0 ? m_index.value() : -m_index.value(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
Index rowOffset() const EIGEN_NOEXCEPT { return m_index.value()>0 ? 0 : -m_index.value(); }
|
EIGEN_STRONG_INLINE Index rowOffset() const { return m_index.value()>0 ? 0 : -m_index.value(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
Index colOffset() const EIGEN_NOEXCEPT { return m_index.value()>0 ? m_index.value() : 0; }
|
EIGEN_STRONG_INLINE Index colOffset() const { return m_index.value()>0 ? m_index.value() : 0; }
|
||||||
// trigger a compile-time error if 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) const;
|
||||||
template<int LoadMode> typename MatrixType::PacketReturnType packet(Index,Index) const;
|
template<int LoadMode> typename MatrixType::PacketReturnType packet(Index,Index) const;
|
||||||
@@ -191,8 +195,7 @@ MatrixBase<Derived>::diagonal()
|
|||||||
|
|
||||||
/** This is the const version of diagonal(). */
|
/** This is the const version of diagonal(). */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC inline
|
EIGEN_DEVICE_FUNC inline typename MatrixBase<Derived>::ConstDiagonalReturnType
|
||||||
const typename MatrixBase<Derived>::ConstDiagonalReturnType
|
|
||||||
MatrixBase<Derived>::diagonal() const
|
MatrixBase<Derived>::diagonal() const
|
||||||
{
|
{
|
||||||
return ConstDiagonalReturnType(derived());
|
return ConstDiagonalReturnType(derived());
|
||||||
@@ -210,18 +213,18 @@ MatrixBase<Derived>::diagonal() const
|
|||||||
*
|
*
|
||||||
* \sa MatrixBase::diagonal(), class Diagonal */
|
* \sa MatrixBase::diagonal(), class Diagonal */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC inline Diagonal<Derived, DynamicIndex>
|
EIGEN_DEVICE_FUNC inline typename MatrixBase<Derived>::DiagonalDynamicIndexReturnType
|
||||||
MatrixBase<Derived>::diagonal(Index index)
|
MatrixBase<Derived>::diagonal(Index index)
|
||||||
{
|
{
|
||||||
return Diagonal<Derived, DynamicIndex>(derived(), index);
|
return DiagonalDynamicIndexReturnType(derived(), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This is the const version of diagonal(Index). */
|
/** This is the const version of diagonal(Index). */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC inline const Diagonal<const Derived, DynamicIndex>
|
EIGEN_DEVICE_FUNC inline typename MatrixBase<Derived>::ConstDiagonalDynamicIndexReturnType
|
||||||
MatrixBase<Derived>::diagonal(Index index) const
|
MatrixBase<Derived>::diagonal(Index index) const
|
||||||
{
|
{
|
||||||
return Diagonal<const Derived, DynamicIndex>(derived(), index);
|
return ConstDiagonalDynamicIndexReturnType(derived(), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns an expression of the \a DiagIndex-th sub or super diagonal of the matrix \c *this
|
/** \returns an expression of the \a DiagIndex-th sub or super diagonal of the matrix \c *this
|
||||||
@@ -237,21 +240,19 @@ MatrixBase<Derived>::diagonal(Index index) const
|
|||||||
* \sa MatrixBase::diagonal(), class Diagonal */
|
* \sa MatrixBase::diagonal(), class Diagonal */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<int Index_>
|
template<int Index_>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC inline typename MatrixBase<Derived>::template DiagonalIndexReturnType<Index_>::Type
|
||||||
inline Diagonal<Derived, Index_>
|
|
||||||
MatrixBase<Derived>::diagonal()
|
MatrixBase<Derived>::diagonal()
|
||||||
{
|
{
|
||||||
return Diagonal<Derived, Index_>(derived());
|
return typename DiagonalIndexReturnType<Index_>::Type(derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This is the const version of diagonal<int>(). */
|
/** This is the const version of diagonal<int>(). */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<int Index_>
|
template<int Index_>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC inline typename MatrixBase<Derived>::template ConstDiagonalIndexReturnType<Index_>::Type
|
||||||
inline const Diagonal<const Derived, Index_>
|
|
||||||
MatrixBase<Derived>::diagonal() const
|
MatrixBase<Derived>::diagonal() const
|
||||||
{
|
{
|
||||||
return Diagonal<const Derived, Index_>(derived());
|
return typename ConstDiagonalIndexReturnType<Index_>::Type(derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|||||||
@@ -83,30 +83,6 @@ class DiagonalBase : public EigenBase<Derived>
|
|||||||
{
|
{
|
||||||
return DiagonalWrapper<const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar,DiagonalVectorType,product) >(scalar * other.diagonal());
|
return DiagonalWrapper<const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar,DiagonalVectorType,product) >(scalar * other.diagonal());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
inline unspecified_expression_type
|
|
||||||
#else
|
|
||||||
inline const DiagonalWrapper<const EIGEN_CWISE_BINARY_RETURN_TYPE(DiagonalVectorType,typename OtherDerived::DiagonalVectorType,sum) >
|
|
||||||
#endif
|
|
||||||
operator+(const DiagonalBase<OtherDerived>& other) const
|
|
||||||
{
|
|
||||||
return (diagonal() + other.diagonal()).asDiagonal();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
inline unspecified_expression_type
|
|
||||||
#else
|
|
||||||
inline const DiagonalWrapper<const EIGEN_CWISE_BINARY_RETURN_TYPE(DiagonalVectorType,typename OtherDerived::DiagonalVectorType,difference) >
|
|
||||||
#endif
|
|
||||||
operator-(const DiagonalBase<OtherDerived>& other) const
|
|
||||||
{
|
|
||||||
return (diagonal() - other.diagonal()).asDiagonal();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -178,30 +154,6 @@ class DiagonalMatrix
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline DiagonalMatrix(const Scalar& x, const Scalar& y, const Scalar& z) : m_diagonal(x,y,z) {}
|
inline DiagonalMatrix(const Scalar& x, const Scalar& y, const Scalar& z) : m_diagonal(x,y,z) {}
|
||||||
|
|
||||||
#if EIGEN_HAS_CXX11
|
|
||||||
/** \brief Construct a diagonal matrix with fixed size from an arbitrary number of coefficients. \cpp11
|
|
||||||
*
|
|
||||||
* There exists C++98 anologue constructors for fixed-size diagonal matrices having 2 or 3 coefficients.
|
|
||||||
*
|
|
||||||
* \warning To construct a diagonal matrix of fixed size, the number of values passed to this
|
|
||||||
* constructor must match the fixed dimension of \c *this.
|
|
||||||
*
|
|
||||||
* \sa DiagonalMatrix(const Scalar&, const Scalar&)
|
|
||||||
* \sa DiagonalMatrix(const Scalar&, const Scalar&, const Scalar&)
|
|
||||||
*/
|
|
||||||
template <typename... ArgTypes>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
DiagonalMatrix(const Scalar& a0, const Scalar& a1, const Scalar& a2, const ArgTypes&... args)
|
|
||||||
: m_diagonal(a0, a1, a2, args...) {}
|
|
||||||
|
|
||||||
/** \brief Constructs a DiagonalMatrix and initializes it by elements given by an initializer list of initializer
|
|
||||||
* lists \cpp11
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
explicit EIGEN_STRONG_INLINE DiagonalMatrix(const std::initializer_list<std::initializer_list<Scalar>>& list)
|
|
||||||
: m_diagonal(list) {}
|
|
||||||
#endif // EIGEN_HAS_CXX11
|
|
||||||
|
|
||||||
/** Copy constructor. */
|
/** Copy constructor. */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
@@ -366,7 +318,7 @@ template<> struct AssignmentKind<DenseShape,DiagonalShape> { typedef Diagonal2De
|
|||||||
template< typename DstXprType, typename SrcXprType, typename Functor>
|
template< typename DstXprType, typename SrcXprType, typename Functor>
|
||||||
struct Assignment<DstXprType, SrcXprType, Functor, Diagonal2Dense>
|
struct Assignment<DstXprType, SrcXprType, Functor, Diagonal2Dense>
|
||||||
{
|
{
|
||||||
static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar> &/*func*/)
|
static EIGEN_DEVICE_FUNC void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar> &/*func*/)
|
||||||
{
|
{
|
||||||
Index dstRows = src.rows();
|
Index dstRows = src.rows();
|
||||||
Index dstCols = src.cols();
|
Index dstCols = src.cols();
|
||||||
|
|||||||
@@ -18,9 +18,14 @@ namespace internal {
|
|||||||
// with mismatched types, the compiler emits errors about failing to instantiate cwiseProduct BEFORE
|
// with mismatched types, the compiler emits errors about failing to instantiate cwiseProduct BEFORE
|
||||||
// looking at the static assertions. Thus this is a trick to get better compile errors.
|
// looking at the static assertions. Thus this is a trick to get better compile errors.
|
||||||
template<typename T, typename U,
|
template<typename T, typename U,
|
||||||
bool NeedToTranspose = T::IsVectorAtCompileTime && U::IsVectorAtCompileTime &&
|
// the NeedToTranspose condition here is taken straight from Assign.h
|
||||||
((int(T::RowsAtCompileTime) == 1 && int(U::ColsAtCompileTime) == 1) ||
|
bool NeedToTranspose = T::IsVectorAtCompileTime
|
||||||
(int(T::ColsAtCompileTime) == 1 && int(U::RowsAtCompileTime) == 1))>
|
&& U::IsVectorAtCompileTime
|
||||||
|
&& ((int(T::RowsAtCompileTime) == 1 && int(U::ColsAtCompileTime) == 1)
|
||||||
|
| // FIXME | instead of || to please GCC 4.4.0 stupid warning "suggest parentheses around &&".
|
||||||
|
// revert to || as soon as not needed anymore.
|
||||||
|
(int(T::ColsAtCompileTime) == 1 && int(U::RowsAtCompileTime) == 1))
|
||||||
|
>
|
||||||
struct dot_nocheck
|
struct dot_nocheck
|
||||||
{
|
{
|
||||||
typedef scalar_conj_product_op<typename traits<T>::Scalar,typename traits<U>::Scalar> conj_prod;
|
typedef scalar_conj_product_op<typename traits<T>::Scalar,typename traits<U>::Scalar> conj_prod;
|
||||||
@@ -202,7 +207,7 @@ struct lpNorm_selector
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
static inline RealScalar run(const MatrixBase<Derived>& m)
|
static inline RealScalar run(const MatrixBase<Derived>& m)
|
||||||
{
|
{
|
||||||
EIGEN_USING_STD(pow)
|
EIGEN_USING_STD_MATH(pow)
|
||||||
return pow(m.cwiseAbs().array().pow(p).sum(), RealScalar(1)/p);
|
return pow(m.cwiseAbs().array().pow(p).sum(), RealScalar(1)/p);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -32,9 +32,8 @@ template<typename Derived> struct EigenBase
|
|||||||
|
|
||||||
/** \brief The interface type of indices
|
/** \brief The interface type of indices
|
||||||
* \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE.
|
* \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.
|
* \sa StorageIndex, \ref TopicPreprocessorDirectives.
|
||||||
* DEPRECATED: Since Eigen 3.3, its usage is deprecated. Use Eigen::Index instead.
|
|
||||||
* Deprecation is not marked with a doxygen comment because there are too many existing usages to add the deprecation attribute.
|
|
||||||
*/
|
*/
|
||||||
typedef Eigen::Index Index;
|
typedef Eigen::Index Index;
|
||||||
|
|
||||||
@@ -56,15 +55,15 @@ template<typename Derived> struct EigenBase
|
|||||||
{ return *static_cast<const Derived*>(this); }
|
{ return *static_cast<const Derived*>(this); }
|
||||||
|
|
||||||
/** \returns the number of rows. \sa cols(), RowsAtCompileTime */
|
/** \returns the number of rows. \sa cols(), RowsAtCompileTime */
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index rows() const EIGEN_NOEXCEPT { return derived().rows(); }
|
inline Index rows() const { return derived().rows(); }
|
||||||
/** \returns the number of columns. \sa rows(), ColsAtCompileTime*/
|
/** \returns the number of columns. \sa rows(), ColsAtCompileTime*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index cols() const EIGEN_NOEXCEPT { return derived().cols(); }
|
inline Index cols() const { return derived().cols(); }
|
||||||
/** \returns the number of coefficients, which is rows()*cols().
|
/** \returns the number of coefficients, which is rows()*cols().
|
||||||
* \sa rows(), cols(), SizeAtCompileTime. */
|
* \sa rows(), cols(), SizeAtCompileTime. */
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index size() const EIGEN_NOEXCEPT { return rows() * cols(); }
|
inline Index size() const { return rows() * cols(); }
|
||||||
|
|
||||||
/** \internal Don't use it, but do the equivalent: \code dst = *this; \endcode */
|
/** \internal Don't use it, but do the equivalent: \code dst = *this; \endcode */
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
|
|||||||
@@ -41,14 +41,10 @@ template<typename ExpressionType> class ForceAlignedAccess
|
|||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit inline ForceAlignedAccess(const ExpressionType& matrix) : m_expression(matrix) {}
|
EIGEN_DEVICE_FUNC explicit inline ForceAlignedAccess(const ExpressionType& matrix) : m_expression(matrix) {}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC inline Index rows() const { return m_expression.rows(); }
|
||||||
inline Index rows() const EIGEN_NOEXCEPT { return m_expression.rows(); }
|
EIGEN_DEVICE_FUNC inline Index cols() const { return m_expression.cols(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC inline Index outerStride() const { return m_expression.outerStride(); }
|
||||||
inline Index cols() const EIGEN_NOEXCEPT { return m_expression.cols(); }
|
EIGEN_DEVICE_FUNC inline Index innerStride() const { return m_expression.innerStride(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
|
||||||
inline Index outerStride() const EIGEN_NOEXCEPT { return m_expression.outerStride(); }
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
|
||||||
inline Index innerStride() const EIGEN_NOEXCEPT { return m_expression.innerStride(); }
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline const CoeffReturnType coeff(Index row, Index col) const
|
EIGEN_DEVICE_FUNC inline const CoeffReturnType coeff(Index row, Index col) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,16 +18,6 @@ enum {
|
|||||||
Small = 3
|
Small = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
// Define the threshold value to fallback from the generic matrix-matrix product
|
|
||||||
// implementation (heavy) to the lightweight coeff-based product one.
|
|
||||||
// See generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,GemmProduct>
|
|
||||||
// in products/GeneralMatrixMatrix.h for more details.
|
|
||||||
// TODO This threshold should also be used in the compile-time selector below.
|
|
||||||
#ifndef EIGEN_GEMM_TO_COEFFBASED_THRESHOLD
|
|
||||||
// This default value has been obtained on a Haswell architecture.
|
|
||||||
#define EIGEN_GEMM_TO_COEFFBASED_THRESHOLD 20
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template<int Rows, int Cols, int Depth> struct product_type_selector;
|
template<int Rows, int Cols, int Depth> struct product_type_selector;
|
||||||
@@ -35,7 +25,7 @@ template<int Rows, int Cols, int Depth> struct product_type_selector;
|
|||||||
template<int Size, int MaxSize> struct product_size_category
|
template<int Size, int MaxSize> struct product_size_category
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
#ifndef EIGEN_GPU_COMPILE_PHASE
|
#ifndef EIGEN_CUDA_ARCH
|
||||||
is_large = MaxSize == Dynamic ||
|
is_large = MaxSize == Dynamic ||
|
||||||
Size >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD ||
|
Size >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD ||
|
||||||
(Size==Dynamic && MaxSize>=EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD),
|
(Size==Dynamic && MaxSize>=EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD),
|
||||||
@@ -163,13 +153,13 @@ template<typename Scalar,int Size,int MaxSize,bool Cond> struct gemv_static_vect
|
|||||||
template<typename Scalar,int Size,int MaxSize>
|
template<typename Scalar,int Size,int MaxSize>
|
||||||
struct gemv_static_vector_if<Scalar,Size,MaxSize,false>
|
struct gemv_static_vector_if<Scalar,Size,MaxSize,false>
|
||||||
{
|
{
|
||||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Scalar* data() { eigen_internal_assert(false && "should never be called"); return 0; }
|
EIGEN_STRONG_INLINE Scalar* data() { eigen_internal_assert(false && "should never be called"); return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Scalar,int Size>
|
template<typename Scalar,int Size>
|
||||||
struct gemv_static_vector_if<Scalar,Size,Dynamic,true>
|
struct gemv_static_vector_if<Scalar,Size,Dynamic,true>
|
||||||
{
|
{
|
||||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Scalar* data() { return 0; }
|
EIGEN_STRONG_INLINE Scalar* data() { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Scalar,int Size,int MaxSize>
|
template<typename Scalar,int Size,int MaxSize>
|
||||||
@@ -228,7 +218,8 @@ template<> struct gemv_dense_selector<OnTheRight,ColMajor,true>
|
|||||||
ActualLhsType actualLhs = LhsBlasTraits::extract(lhs);
|
ActualLhsType actualLhs = LhsBlasTraits::extract(lhs);
|
||||||
ActualRhsType actualRhs = RhsBlasTraits::extract(rhs);
|
ActualRhsType actualRhs = RhsBlasTraits::extract(rhs);
|
||||||
|
|
||||||
ResScalar actualAlpha = combine_scalar_factors(alpha, lhs, rhs);
|
ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(lhs)
|
||||||
|
* RhsBlasTraits::extractScalarFactor(rhs);
|
||||||
|
|
||||||
// make sure Dest is a compile-time vector type (bug 1166)
|
// make sure Dest is a compile-time vector type (bug 1166)
|
||||||
typedef typename conditional<Dest::IsVectorAtCompileTime, Dest, typename Dest::ColXpr>::type ActualDest;
|
typedef typename conditional<Dest::IsVectorAtCompileTime, Dest, typename Dest::ColXpr>::type ActualDest;
|
||||||
@@ -238,7 +229,7 @@ template<> struct gemv_dense_selector<OnTheRight,ColMajor,true>
|
|||||||
// on, the other hand it is good for the cache to pack the vector anyways...
|
// on, the other hand it is good for the cache to pack the vector anyways...
|
||||||
EvalToDestAtCompileTime = (ActualDest::InnerStrideAtCompileTime==1),
|
EvalToDestAtCompileTime = (ActualDest::InnerStrideAtCompileTime==1),
|
||||||
ComplexByReal = (NumTraits<LhsScalar>::IsComplex) && (!NumTraits<RhsScalar>::IsComplex),
|
ComplexByReal = (NumTraits<LhsScalar>::IsComplex) && (!NumTraits<RhsScalar>::IsComplex),
|
||||||
MightCannotUseDest = ((!EvalToDestAtCompileTime) || ComplexByReal) && (ActualDest::MaxSizeAtCompileTime!=0)
|
MightCannotUseDest = (!EvalToDestAtCompileTime) || ComplexByReal
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef const_blas_data_mapper<LhsScalar,Index,ColMajor> LhsMapper;
|
typedef const_blas_data_mapper<LhsScalar,Index,ColMajor> LhsMapper;
|
||||||
@@ -319,12 +310,13 @@ template<> struct gemv_dense_selector<OnTheRight,RowMajor,true>
|
|||||||
typename add_const<ActualLhsType>::type actualLhs = LhsBlasTraits::extract(lhs);
|
typename add_const<ActualLhsType>::type actualLhs = LhsBlasTraits::extract(lhs);
|
||||||
typename add_const<ActualRhsType>::type actualRhs = RhsBlasTraits::extract(rhs);
|
typename add_const<ActualRhsType>::type actualRhs = RhsBlasTraits::extract(rhs);
|
||||||
|
|
||||||
ResScalar actualAlpha = combine_scalar_factors(alpha, lhs, rhs);
|
ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(lhs)
|
||||||
|
* RhsBlasTraits::extractScalarFactor(rhs);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
// FIXME find a way to allow an inner stride on the result if packet_traits<Scalar>::size==1
|
// 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...
|
// on, the other hand it is good for the cache to pack the vector anyways...
|
||||||
DirectlyUseRhs = ActualRhsTypeCleaned::InnerStrideAtCompileTime==1 || ActualRhsTypeCleaned::MaxSizeAtCompileTime==0
|
DirectlyUseRhs = ActualRhsTypeCleaned::InnerStrideAtCompileTime==1
|
||||||
};
|
};
|
||||||
|
|
||||||
gemv_static_vector_if<RhsScalar,ActualRhsTypeCleaned::SizeAtCompileTime,ActualRhsTypeCleaned::MaxSizeAtCompileTime,!DirectlyUseRhs> static_rhs;
|
gemv_static_vector_if<RhsScalar,ActualRhsTypeCleaned::SizeAtCompileTime,ActualRhsTypeCleaned::MaxSizeAtCompileTime,!DirectlyUseRhs> static_rhs;
|
||||||
@@ -394,8 +386,7 @@ template<> struct gemv_dense_selector<OnTheRight,RowMajor,false>
|
|||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC inline const Product<Derived, OtherDerived>
|
||||||
const Product<Derived, OtherDerived>
|
|
||||||
MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
|
MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
|
||||||
{
|
{
|
||||||
// A note regarding the function declaration: In MSVC, this function will sometimes
|
// A note regarding the function declaration: In MSVC, this function will sometimes
|
||||||
@@ -437,8 +428,7 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
|
|||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC const Product<Derived,OtherDerived,LazyProduct>
|
||||||
const Product<Derived,OtherDerived,LazyProduct>
|
|
||||||
MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &other) const
|
MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &other) const
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
|
|||||||
@@ -44,29 +44,23 @@ struct default_packet_traits
|
|||||||
enum {
|
enum {
|
||||||
HasHalfPacket = 0,
|
HasHalfPacket = 0,
|
||||||
|
|
||||||
HasAdd = 1,
|
HasAdd = 1,
|
||||||
HasSub = 1,
|
HasSub = 1,
|
||||||
HasShift = 1,
|
HasMul = 1,
|
||||||
HasMul = 1,
|
HasNegate = 1,
|
||||||
HasNegate = 1,
|
HasAbs = 1,
|
||||||
HasAbs = 1,
|
HasArg = 0,
|
||||||
HasArg = 0,
|
HasAbs2 = 1,
|
||||||
HasAbs2 = 1,
|
HasMin = 1,
|
||||||
HasAbsDiff = 0,
|
HasMax = 1,
|
||||||
HasMin = 1,
|
HasConj = 1,
|
||||||
HasMax = 1,
|
|
||||||
HasConj = 1,
|
|
||||||
HasSetLinear = 1,
|
HasSetLinear = 1,
|
||||||
HasBlend = 0,
|
HasBlend = 0,
|
||||||
// This flag is used to indicate whether packet comparison is supported.
|
|
||||||
// pcmp_eq, pcmp_lt and pcmp_le should be defined for it to be true.
|
|
||||||
HasCmp = 0,
|
|
||||||
|
|
||||||
HasDiv = 0,
|
HasDiv = 0,
|
||||||
HasSqrt = 0,
|
HasSqrt = 0,
|
||||||
HasRsqrt = 0,
|
HasRsqrt = 0,
|
||||||
HasExp = 0,
|
HasExp = 0,
|
||||||
HasExpm1 = 0,
|
|
||||||
HasLog = 0,
|
HasLog = 0,
|
||||||
HasLog1p = 0,
|
HasLog1p = 0,
|
||||||
HasLog10 = 0,
|
HasLog10 = 0,
|
||||||
@@ -87,18 +81,14 @@ struct default_packet_traits
|
|||||||
HasPolygamma = 0,
|
HasPolygamma = 0,
|
||||||
HasErf = 0,
|
HasErf = 0,
|
||||||
HasErfc = 0,
|
HasErfc = 0,
|
||||||
HasNdtri = 0,
|
|
||||||
HasBessel = 0,
|
|
||||||
HasIGamma = 0,
|
HasIGamma = 0,
|
||||||
HasIGammaDerA = 0,
|
|
||||||
HasGammaSampleDerAlpha = 0,
|
|
||||||
HasIGammac = 0,
|
HasIGammac = 0,
|
||||||
HasBetaInc = 0,
|
HasBetaInc = 0,
|
||||||
|
|
||||||
HasRound = 0,
|
HasRound = 0,
|
||||||
HasRint = 0,
|
|
||||||
HasFloor = 0,
|
HasFloor = 0,
|
||||||
HasCeil = 0,
|
HasCeil = 0,
|
||||||
|
|
||||||
HasSign = 0
|
HasSign = 0
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -129,22 +119,6 @@ template<typename T> struct packet_traits : default_packet_traits
|
|||||||
|
|
||||||
template<typename T> struct packet_traits<const T> : packet_traits<T> { };
|
template<typename T> struct packet_traits<const T> : packet_traits<T> { };
|
||||||
|
|
||||||
template<typename T> struct unpacket_traits
|
|
||||||
{
|
|
||||||
typedef T type;
|
|
||||||
typedef T half;
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
size = 1,
|
|
||||||
alignment = 1,
|
|
||||||
vectorizable = false,
|
|
||||||
masked_load_available=false,
|
|
||||||
masked_store_available=false
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T> struct unpacket_traits<const T> : unpacket_traits<T> { };
|
|
||||||
|
|
||||||
template <typename Src, typename Tgt> struct type_casting_traits {
|
template <typename Src, typename Tgt> struct type_casting_traits {
|
||||||
enum {
|
enum {
|
||||||
VectorizedCast = 0,
|
VectorizedCast = 0,
|
||||||
@@ -153,34 +127,6 @@ template <typename Src, typename Tgt> struct type_casting_traits {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \internal Wrapper to ensure that multiple packet types can map to the same
|
|
||||||
same underlying vector type. */
|
|
||||||
template<typename T, int unique_id = 0>
|
|
||||||
struct eigen_packet_wrapper
|
|
||||||
{
|
|
||||||
EIGEN_ALWAYS_INLINE operator T&() { return m_val; }
|
|
||||||
EIGEN_ALWAYS_INLINE operator const T&() const { return m_val; }
|
|
||||||
EIGEN_ALWAYS_INLINE eigen_packet_wrapper() {};
|
|
||||||
EIGEN_ALWAYS_INLINE eigen_packet_wrapper(const T &v) : m_val(v) {}
|
|
||||||
EIGEN_ALWAYS_INLINE eigen_packet_wrapper& operator=(const T &v) {
|
|
||||||
m_val = v;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
T m_val;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/** \internal A convenience utility for determining if the type is a scalar.
|
|
||||||
* This is used to enable some generic packet implementations.
|
|
||||||
*/
|
|
||||||
template<typename Packet>
|
|
||||||
struct is_scalar {
|
|
||||||
typedef typename unpacket_traits<Packet>::type Scalar;
|
|
||||||
enum {
|
|
||||||
value = internal::is_same<Packet, Scalar>::value
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \internal \returns static_cast<TgtType>(a) (coeff-wise) */
|
/** \internal \returns static_cast<TgtType>(a) (coeff-wise) */
|
||||||
template <typename SrcPacket, typename TgtPacket>
|
template <typename SrcPacket, typename TgtPacket>
|
||||||
@@ -193,406 +139,75 @@ EIGEN_DEVICE_FUNC inline TgtPacket
|
|||||||
pcast(const SrcPacket& a, const SrcPacket& /*b*/) {
|
pcast(const SrcPacket& a, const SrcPacket& /*b*/) {
|
||||||
return static_cast<TgtPacket>(a);
|
return static_cast<TgtPacket>(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename SrcPacket, typename TgtPacket>
|
template <typename SrcPacket, typename TgtPacket>
|
||||||
EIGEN_DEVICE_FUNC inline TgtPacket
|
EIGEN_DEVICE_FUNC inline TgtPacket
|
||||||
pcast(const SrcPacket& a, const SrcPacket& /*b*/, const SrcPacket& /*c*/, const SrcPacket& /*d*/) {
|
pcast(const SrcPacket& a, const SrcPacket& /*b*/, const SrcPacket& /*c*/, const SrcPacket& /*d*/) {
|
||||||
return static_cast<TgtPacket>(a);
|
return static_cast<TgtPacket>(a);
|
||||||
}
|
}
|
||||||
template <typename SrcPacket, typename TgtPacket>
|
|
||||||
EIGEN_DEVICE_FUNC inline TgtPacket
|
|
||||||
pcast(const SrcPacket& a, const SrcPacket& /*b*/, const SrcPacket& /*c*/, const SrcPacket& /*d*/,
|
|
||||||
const SrcPacket& /*e*/, const SrcPacket& /*f*/, const SrcPacket& /*g*/, const SrcPacket& /*h*/) {
|
|
||||||
return static_cast<TgtPacket>(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal \returns reinterpret_cast<Target>(a) */
|
|
||||||
template <typename Target, typename Packet>
|
|
||||||
EIGEN_DEVICE_FUNC inline Target
|
|
||||||
preinterpret(const Packet& a); /* { return reinterpret_cast<const Target&>(a); } */
|
|
||||||
|
|
||||||
/** \internal \returns a + b (coeff-wise) */
|
/** \internal \returns a + b (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
padd(const Packet& a, const Packet& b) { return a+b; }
|
padd(const Packet& a,
|
||||||
// Avoid compiler warning for boolean algebra.
|
const Packet& b) { return a+b; }
|
||||||
template<> EIGEN_DEVICE_FUNC inline bool
|
|
||||||
padd(const bool& a, const bool& b) { return a || b; }
|
|
||||||
|
|
||||||
/** \internal \returns a - b (coeff-wise) */
|
/** \internal \returns a - b (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
psub(const Packet& a, const Packet& b) { return a-b; }
|
psub(const Packet& a,
|
||||||
|
const Packet& b) { return a-b; }
|
||||||
|
|
||||||
/** \internal \returns -a (coeff-wise) */
|
/** \internal \returns -a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
pnegate(const Packet& a) { return -a; }
|
pnegate(const Packet& a) { return -a; }
|
||||||
|
|
||||||
template<> EIGEN_DEVICE_FUNC inline bool
|
|
||||||
pnegate(const bool& a) { return !a; }
|
|
||||||
|
|
||||||
/** \internal \returns conj(a) (coeff-wise) */
|
/** \internal \returns conj(a) (coeff-wise) */
|
||||||
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
pconj(const Packet& a) { return numext::conj(a); }
|
pconj(const Packet& a) { return numext::conj(a); }
|
||||||
|
|
||||||
/** \internal \returns a * b (coeff-wise) */
|
/** \internal \returns a * b (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
pmul(const Packet& a, const Packet& b) { return a*b; }
|
pmul(const Packet& a,
|
||||||
// Avoid compiler warning for boolean algebra.
|
const Packet& b) { return a*b; }
|
||||||
template<> EIGEN_DEVICE_FUNC inline bool
|
|
||||||
pmul(const bool& a, const bool& b) { return a && b; }
|
|
||||||
|
|
||||||
/** \internal \returns a / b (coeff-wise) */
|
/** \internal \returns a / b (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
pdiv(const Packet& a, const Packet& b) { return a/b; }
|
pdiv(const Packet& a,
|
||||||
|
const Packet& b) { return a/b; }
|
||||||
|
|
||||||
// In the generic case, memset to all one bits.
|
/** \internal \returns the min of \a a and \a b (coeff-wise) */
|
||||||
template<typename Packet, typename EnableIf = void>
|
|
||||||
struct ptrue_impl {
|
|
||||||
static EIGEN_DEVICE_FUNC inline Packet run(const Packet& /*a*/){
|
|
||||||
Packet b;
|
|
||||||
memset(static_cast<void*>(&b), 0xff, sizeof(Packet));
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// For non-trivial scalars, set to Scalar(1) (i.e. a non-zero value).
|
|
||||||
// Although this is technically not a valid bitmask, the scalar path for pselect
|
|
||||||
// uses a comparison to zero, so this should still work in most cases. We don't
|
|
||||||
// have another option, since the scalar type requires initialization.
|
|
||||||
template<typename T>
|
|
||||||
struct ptrue_impl<T,
|
|
||||||
typename internal::enable_if<is_scalar<T>::value && NumTraits<T>::RequireInitialization>::type > {
|
|
||||||
static EIGEN_DEVICE_FUNC inline T run(const T& /*a*/){
|
|
||||||
return T(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \internal \returns one bits. */
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
ptrue(const Packet& a) {
|
pmin(const Packet& a,
|
||||||
return ptrue_impl<Packet>::run(a);
|
const Packet& b) { return numext::mini(a, b); }
|
||||||
}
|
|
||||||
|
|
||||||
// In the general case, memset to zero.
|
/** \internal \returns the max of \a a and \a b (coeff-wise) */
|
||||||
template<typename Packet, typename EnableIf = void>
|
|
||||||
struct pzero_impl {
|
|
||||||
static EIGEN_DEVICE_FUNC inline Packet run(const Packet& /*a*/) {
|
|
||||||
Packet b;
|
|
||||||
memset(static_cast<void*>(&b), 0x00, sizeof(Packet));
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// For scalars, explicitly set to Scalar(0), since the underlying representation
|
|
||||||
// for zero may not consist of all-zero bits.
|
|
||||||
template<typename T>
|
|
||||||
struct pzero_impl<T,
|
|
||||||
typename internal::enable_if<is_scalar<T>::value>::type> {
|
|
||||||
static EIGEN_DEVICE_FUNC inline T run(const T& /*a*/) {
|
|
||||||
return T(0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \internal \returns packet of zeros */
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
pzero(const Packet& a) {
|
pmax(const Packet& a,
|
||||||
return pzero_impl<Packet>::run(a);
|
const Packet& b) { return numext::maxi(a, b); }
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal \returns a <= b as a bit mask */
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
|
||||||
pcmp_le(const Packet& a, const Packet& b) { return a<=b ? ptrue(a) : pzero(a); }
|
|
||||||
|
|
||||||
/** \internal \returns a < b as a bit mask */
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
|
||||||
pcmp_lt(const Packet& a, const Packet& b) { return a<b ? ptrue(a) : pzero(a); }
|
|
||||||
|
|
||||||
/** \internal \returns a == b as a bit mask */
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
|
||||||
pcmp_eq(const Packet& a, const Packet& b) { return a==b ? ptrue(a) : pzero(a); }
|
|
||||||
|
|
||||||
/** \internal \returns a < b or a==NaN or b==NaN as a bit mask */
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
|
||||||
pcmp_lt_or_nan(const Packet& a, const Packet& b) { return a>=b ? pzero(a) : ptrue(a); }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct bit_and {
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR EIGEN_ALWAYS_INLINE T operator()(const T& a, const T& b) const {
|
|
||||||
return a & b;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct bit_or {
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR EIGEN_ALWAYS_INLINE T operator()(const T& a, const T& b) const {
|
|
||||||
return a | b;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct bit_xor {
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR EIGEN_ALWAYS_INLINE T operator()(const T& a, const T& b) const {
|
|
||||||
return a ^ b;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct bit_not {
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR EIGEN_ALWAYS_INLINE T operator()(const T& a) const {
|
|
||||||
return ~a;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Use operators &, |, ^, ~.
|
|
||||||
template<typename T>
|
|
||||||
struct operator_bitwise_helper {
|
|
||||||
EIGEN_DEVICE_FUNC static inline T bitwise_and(const T& a, const T& b) { return bit_and<T>()(a, b); }
|
|
||||||
EIGEN_DEVICE_FUNC static inline T bitwise_or(const T& a, const T& b) { return bit_or<T>()(a, b); }
|
|
||||||
EIGEN_DEVICE_FUNC static inline T bitwise_xor(const T& a, const T& b) { return bit_xor<T>()(a, b); }
|
|
||||||
EIGEN_DEVICE_FUNC static inline T bitwise_not(const T& a) { return bit_not<T>()(a); }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Apply binary operations byte-by-byte
|
|
||||||
template<typename T>
|
|
||||||
struct bytewise_bitwise_helper {
|
|
||||||
EIGEN_DEVICE_FUNC static inline T bitwise_and(const T& a, const T& b) {
|
|
||||||
return binary(a, b, bit_and<unsigned char>());
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC static inline T bitwise_or(const T& a, const T& b) {
|
|
||||||
return binary(a, b, bit_or<unsigned char>());
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC static inline T bitwise_xor(const T& a, const T& b) {
|
|
||||||
return binary(a, b, bit_xor<unsigned char>());
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC static inline T bitwise_not(const T& a) {
|
|
||||||
return unary(a,bit_not<unsigned char>());
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template<typename Op>
|
|
||||||
EIGEN_DEVICE_FUNC static inline T unary(const T& a, Op op) {
|
|
||||||
const unsigned char* a_ptr = reinterpret_cast<const unsigned char*>(&a);
|
|
||||||
T c;
|
|
||||||
unsigned char* c_ptr = reinterpret_cast<unsigned char*>(&c);
|
|
||||||
for (size_t i = 0; i < sizeof(T); ++i) {
|
|
||||||
*c_ptr++ = op(*a_ptr++);
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Op>
|
|
||||||
EIGEN_DEVICE_FUNC static inline T binary(const T& a, const T& b, Op op) {
|
|
||||||
const unsigned char* a_ptr = reinterpret_cast<const unsigned char*>(&a);
|
|
||||||
const unsigned char* b_ptr = reinterpret_cast<const unsigned char*>(&b);
|
|
||||||
T c;
|
|
||||||
unsigned char* c_ptr = reinterpret_cast<unsigned char*>(&c);
|
|
||||||
for (size_t i = 0; i < sizeof(T); ++i) {
|
|
||||||
*c_ptr++ = op(*a_ptr++, *b_ptr++);
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// In the general case, use byte-by-byte manipulation.
|
|
||||||
template<typename T, typename EnableIf = void>
|
|
||||||
struct bitwise_helper : public bytewise_bitwise_helper<T> {};
|
|
||||||
|
|
||||||
// For integers or non-trivial scalars, use binary operators.
|
|
||||||
template<typename T>
|
|
||||||
struct bitwise_helper<T,
|
|
||||||
typename internal::enable_if<
|
|
||||||
is_scalar<T>::value && (NumTraits<T>::IsInteger || NumTraits<T>::RequireInitialization)>::type
|
|
||||||
> : public operator_bitwise_helper<T> {};
|
|
||||||
|
|
||||||
/** \internal \returns the bitwise and of \a a and \a b */
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
|
||||||
pand(const Packet& a, const Packet& b) {
|
|
||||||
return bitwise_helper<Packet>::bitwise_and(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal \returns the bitwise or of \a a and \a b */
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
|
||||||
por(const Packet& a, const Packet& b) {
|
|
||||||
return bitwise_helper<Packet>::bitwise_or(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal \returns the bitwise xor of \a a and \a b */
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
|
||||||
pxor(const Packet& a, const Packet& b) {
|
|
||||||
return bitwise_helper<Packet>::bitwise_xor(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal \returns the bitwise not of \a a */
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
|
||||||
pnot(const Packet& a) {
|
|
||||||
return bitwise_helper<Packet>::bitwise_not(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal \returns the bitwise and of \a a and not \a b */
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
|
||||||
pandnot(const Packet& a, const Packet& b) { return pand(a, pnot(b)); }
|
|
||||||
|
|
||||||
// In the general case, use bitwise select.
|
|
||||||
template<typename Packet, typename EnableIf = void>
|
|
||||||
struct pselect_impl {
|
|
||||||
static EIGEN_DEVICE_FUNC inline Packet run(const Packet& mask, const Packet& a, const Packet& b) {
|
|
||||||
return por(pand(a,mask),pandnot(b,mask));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// For scalars, use ternary select.
|
|
||||||
template<typename Packet>
|
|
||||||
struct pselect_impl<Packet,
|
|
||||||
typename internal::enable_if<is_scalar<Packet>::value>::type > {
|
|
||||||
static EIGEN_DEVICE_FUNC inline Packet run(const Packet& mask, const Packet& a, const Packet& b) {
|
|
||||||
return numext::equal_strict(mask, Packet(0)) ? b : a;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \internal \returns \a or \b for each field in packet according to \mask */
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
|
||||||
pselect(const Packet& mask, const Packet& a, const Packet& b) {
|
|
||||||
return pselect_impl<Packet>::run(mask, a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> EIGEN_DEVICE_FUNC inline bool pselect<bool>(
|
|
||||||
const bool& cond, const bool& a, const bool& b) {
|
|
||||||
return cond ? a : b;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal \returns the min or of \a a and \a b (coeff-wise)
|
|
||||||
If either \a a or \a b are NaN, the result is implementation defined. */
|
|
||||||
template<int NaNPropagation>
|
|
||||||
struct pminmax_impl {
|
|
||||||
template <typename Packet, typename Op>
|
|
||||||
static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a, const Packet& b, Op op) {
|
|
||||||
return op(a,b);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \internal \returns the min or max of \a a and \a b (coeff-wise)
|
|
||||||
If either \a a or \a b are NaN, NaN is returned. */
|
|
||||||
template<>
|
|
||||||
struct pminmax_impl<PropagateNaN> {
|
|
||||||
template <typename Packet, typename Op>
|
|
||||||
static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a, const Packet& b, Op op) {
|
|
||||||
Packet not_nan_mask_a = pcmp_eq(a, a);
|
|
||||||
Packet not_nan_mask_b = pcmp_eq(b, b);
|
|
||||||
return pselect(not_nan_mask_a,
|
|
||||||
pselect(not_nan_mask_b, op(a, b), b),
|
|
||||||
a);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \internal \returns the min or max of \a a and \a b (coeff-wise)
|
|
||||||
If both \a a and \a b are NaN, NaN is returned.
|
|
||||||
Equivalent to std::fmin(a, b). */
|
|
||||||
template<>
|
|
||||||
struct pminmax_impl<PropagateNumbers> {
|
|
||||||
template <typename Packet, typename Op>
|
|
||||||
static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a, const Packet& b, Op op) {
|
|
||||||
Packet not_nan_mask_a = pcmp_eq(a, a);
|
|
||||||
Packet not_nan_mask_b = pcmp_eq(b, b);
|
|
||||||
return pselect(not_nan_mask_a,
|
|
||||||
pselect(not_nan_mask_b, op(a, b), a),
|
|
||||||
b);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef SYCL_DEVICE_ONLY
|
|
||||||
#define EIGEN_BINARY_OP_NAN_PROPAGATION(Type, Func) Func
|
|
||||||
#else
|
|
||||||
#define EIGEN_BINARY_OP_NAN_PROPAGATION(Type, Func) \
|
|
||||||
[](const Type& a, const Type& b) { \
|
|
||||||
return Func(a, b);}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \internal \returns the min of \a a and \a b (coeff-wise).
|
|
||||||
If \a a or \b b is NaN, the return value is implementation defined. */
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
|
||||||
pmin(const Packet& a, const Packet& b) { return numext::mini(a,b); }
|
|
||||||
|
|
||||||
/** \internal \returns the min of \a a and \a b (coeff-wise).
|
|
||||||
NaNPropagation determines the NaN propagation semantics. */
|
|
||||||
template <int NaNPropagation, typename Packet>
|
|
||||||
EIGEN_DEVICE_FUNC inline Packet pmin(const Packet& a, const Packet& b) {
|
|
||||||
return pminmax_impl<NaNPropagation>::run(a, b, EIGEN_BINARY_OP_NAN_PROPAGATION(Packet, (pmin<Packet>)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal \returns the max of \a a and \a b (coeff-wise)
|
|
||||||
If \a a or \b b is NaN, the return value is implementation defined. */
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
|
||||||
pmax(const Packet& a, const Packet& b) { return numext::maxi(a, b); }
|
|
||||||
|
|
||||||
/** \internal \returns the max of \a a and \a b (coeff-wise).
|
|
||||||
NaNPropagation determines the NaN propagation semantics. */
|
|
||||||
template <int NaNPropagation, typename Packet>
|
|
||||||
EIGEN_DEVICE_FUNC inline Packet pmax(const Packet& a, const Packet& b) {
|
|
||||||
return pminmax_impl<NaNPropagation>::run(a, b, EIGEN_BINARY_OP_NAN_PROPAGATION(Packet,(pmax<Packet>)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal \returns the absolute value of \a a */
|
/** \internal \returns the absolute value of \a a */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
pabs(const Packet& a) { return numext::abs(a); }
|
pabs(const Packet& a) { using std::abs; return abs(a); }
|
||||||
template<> EIGEN_DEVICE_FUNC inline unsigned int
|
|
||||||
pabs(const unsigned int& a) { return a; }
|
|
||||||
template<> EIGEN_DEVICE_FUNC inline unsigned long
|
|
||||||
pabs(const unsigned long& a) { return a; }
|
|
||||||
template<> EIGEN_DEVICE_FUNC inline unsigned long long
|
|
||||||
pabs(const unsigned long long& a) { return a; }
|
|
||||||
|
|
||||||
/** \internal \returns the addsub value of \a a,b */
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
|
||||||
paddsub(const Packet& a, const Packet& b) {
|
|
||||||
return pselect(peven_mask(a), padd(a, b), psub(a, b));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal \returns the phase angle of \a a */
|
/** \internal \returns the phase angle of \a a */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
parg(const Packet& a) { using numext::arg; return arg(a); }
|
parg(const Packet& a) { using numext::arg; return arg(a); }
|
||||||
|
|
||||||
|
/** \internal \returns the bitwise and of \a a and \a b */
|
||||||
/** \internal \returns \a a logically shifted by N bits to the right */
|
|
||||||
template<int N> EIGEN_DEVICE_FUNC inline int
|
|
||||||
parithmetic_shift_right(const int& a) { return a >> N; }
|
|
||||||
template<int N> EIGEN_DEVICE_FUNC inline long int
|
|
||||||
parithmetic_shift_right(const long int& a) { return a >> N; }
|
|
||||||
|
|
||||||
/** \internal \returns \a a arithmetically shifted by N bits to the right */
|
|
||||||
template<int N> EIGEN_DEVICE_FUNC inline int
|
|
||||||
plogical_shift_right(const int& a) { return static_cast<int>(static_cast<unsigned int>(a) >> N); }
|
|
||||||
template<int N> EIGEN_DEVICE_FUNC inline long int
|
|
||||||
plogical_shift_right(const long int& a) { return static_cast<long>(static_cast<unsigned long>(a) >> N); }
|
|
||||||
|
|
||||||
/** \internal \returns \a a shifted by N bits to the left */
|
|
||||||
template<int N> EIGEN_DEVICE_FUNC inline int
|
|
||||||
plogical_shift_left(const int& a) { return a << N; }
|
|
||||||
template<int N> EIGEN_DEVICE_FUNC inline long int
|
|
||||||
plogical_shift_left(const long int& a) { return a << N; }
|
|
||||||
|
|
||||||
/** \internal \returns the significant and exponent of the underlying floating point numbers
|
|
||||||
* See https://en.cppreference.com/w/cpp/numeric/math/frexp
|
|
||||||
*/
|
|
||||||
template <typename Packet>
|
|
||||||
EIGEN_DEVICE_FUNC inline Packet pfrexp(const Packet& a, Packet& exponent) {
|
|
||||||
int exp;
|
|
||||||
EIGEN_USING_STD(frexp);
|
|
||||||
Packet result = static_cast<Packet>(frexp(a, &exp));
|
|
||||||
exponent = static_cast<Packet>(exp);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal \returns a * 2^((int)exponent)
|
|
||||||
* See https://en.cppreference.com/w/cpp/numeric/math/ldexp
|
|
||||||
*/
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
pldexp(const Packet &a, const Packet &exponent) {
|
pand(const Packet& a, const Packet& b) { return a & b; }
|
||||||
EIGEN_USING_STD(ldexp)
|
|
||||||
return static_cast<Packet>(ldexp(a, static_cast<int>(exponent)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal \returns the min of \a a and \a b (coeff-wise) */
|
/** \internal \returns the bitwise or of \a a and \a b */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
pabsdiff(const Packet& a, const Packet& b) { return pselect(pcmp_lt(a, b), psub(b, a), psub(a, b)); }
|
por(const Packet& a, const Packet& b) { return a | b; }
|
||||||
|
|
||||||
|
/** \internal \returns the bitwise xor of \a a and \a b */
|
||||||
|
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> 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 */
|
/** \internal \returns a packet version of \a *from, from must be 16 bytes aligned */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
@@ -602,22 +217,10 @@ pload(const typename unpacket_traits<Packet>::type* from) { return *from; }
|
|||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
ploadu(const typename unpacket_traits<Packet>::type* from) { return *from; }
|
ploadu(const typename unpacket_traits<Packet>::type* from) { return *from; }
|
||||||
|
|
||||||
/** \internal \returns a packet version of \a *from, (un-aligned masked load)
|
|
||||||
* There is no generic implementation. We only have implementations for specialized
|
|
||||||
* cases. Generic case should not be called.
|
|
||||||
*/
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline
|
|
||||||
typename enable_if<unpacket_traits<Packet>::masked_load_available, Packet>::type
|
|
||||||
ploadu(const typename unpacket_traits<Packet>::type* from, typename unpacket_traits<Packet>::mask_t umask);
|
|
||||||
|
|
||||||
/** \internal \returns a packet with constant coefficients \a a, e.g.: (a,a,a,a) */
|
/** \internal \returns a packet with constant coefficients \a a, e.g.: (a,a,a,a) */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
pset1(const typename unpacket_traits<Packet>::type& a) { return a; }
|
pset1(const typename unpacket_traits<Packet>::type& a) { return a; }
|
||||||
|
|
||||||
/** \internal \returns a packet with constant coefficients set from bits */
|
|
||||||
template<typename Packet,typename BitsType> EIGEN_DEVICE_FUNC inline Packet
|
|
||||||
pset1frombits(BitsType a);
|
|
||||||
|
|
||||||
/** \internal \returns a packet with constant coefficients \a a[0], e.g.: (a[0],a[0],a[0],a[0]) */
|
/** \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
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
pload1(const typename unpacket_traits<Packet>::type *a) { return pset1<Packet>(*a); }
|
pload1(const typename unpacket_traits<Packet>::type *a) { return pset1<Packet>(*a); }
|
||||||
@@ -678,20 +281,6 @@ inline void pbroadcast2(const typename unpacket_traits<Packet>::type *a,
|
|||||||
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet
|
||||||
plset(const typename unpacket_traits<Packet>::type& a) { return a; }
|
plset(const typename unpacket_traits<Packet>::type& a) { return a; }
|
||||||
|
|
||||||
/** \internal \returns a packet with constant coefficients \a a, e.g.: (x, 0, x, 0),
|
|
||||||
where x is the value of all 1-bits. */
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
|
||||||
peven_mask(const Packet& /*a*/) {
|
|
||||||
typedef typename unpacket_traits<Packet>::type Scalar;
|
|
||||||
const size_t n = unpacket_traits<Packet>::size;
|
|
||||||
EIGEN_ALIGN_TO_BOUNDARY(sizeof(Packet)) Scalar elements[n];
|
|
||||||
for(size_t i = 0; i < n; ++i) {
|
|
||||||
memset(elements+i, ((i & 1) == 0 ? 0xff : 0), sizeof(Scalar));
|
|
||||||
}
|
|
||||||
return ploadu<Packet>(elements);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** \internal copy the packet \a from to \a *to, \a to must be 16 bytes aligned */
|
/** \internal copy the packet \a from to \a *to, \a to must be 16 bytes aligned */
|
||||||
template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC 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; }
|
{ (*to) = from; }
|
||||||
@@ -700,15 +289,6 @@ template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline void pstore(
|
|||||||
template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline void pstoreu(Scalar* to, const Packet& from)
|
template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline void pstoreu(Scalar* to, const Packet& from)
|
||||||
{ (*to) = from; }
|
{ (*to) = from; }
|
||||||
|
|
||||||
/** \internal copy the packet \a from to \a *to, (un-aligned store with a mask)
|
|
||||||
* There is no generic implementation. We only have implementations for specialized
|
|
||||||
* cases. Generic case should not be called.
|
|
||||||
*/
|
|
||||||
template<typename Scalar, typename Packet>
|
|
||||||
EIGEN_DEVICE_FUNC inline
|
|
||||||
typename enable_if<unpacket_traits<Packet>::masked_store_available, void>::type
|
|
||||||
pstoreu(Scalar* to, const Packet& from, typename unpacket_traits<Packet>::mask_t umask);
|
|
||||||
|
|
||||||
template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline Packet pgather(const Scalar* from, Index /*stride*/)
|
template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline Packet pgather(const Scalar* from, Index /*stride*/)
|
||||||
{ return ploadu<Packet>(from); }
|
{ return ploadu<Packet>(from); }
|
||||||
|
|
||||||
@@ -718,9 +298,7 @@ pstoreu(Scalar* to, const Packet& from, typename unpacket_traits<Packet>::mask_t
|
|||||||
/** \internal tries to do cache prefetching of \a addr */
|
/** \internal tries to do cache prefetching of \a addr */
|
||||||
template<typename Scalar> EIGEN_DEVICE_FUNC inline void prefetch(const Scalar* addr)
|
template<typename Scalar> EIGEN_DEVICE_FUNC inline void prefetch(const Scalar* addr)
|
||||||
{
|
{
|
||||||
#if defined(EIGEN_HIP_DEVICE_COMPILE)
|
#ifdef __CUDA_ARCH__
|
||||||
// do nothing
|
|
||||||
#elif defined(EIGEN_CUDA_ARCH)
|
|
||||||
#if defined(__LP64__) || EIGEN_OS_WIN64
|
#if defined(__LP64__) || EIGEN_OS_WIN64
|
||||||
// 64-bit pointer operand constraint for inlined asm
|
// 64-bit pointer operand constraint for inlined asm
|
||||||
asm(" prefetch.L1 [ %1 ];" : "=l"(addr) : "l"(addr));
|
asm(" prefetch.L1 [ %1 ];" : "=l"(addr) : "l"(addr));
|
||||||
@@ -733,6 +311,39 @@ template<typename Scalar> EIGEN_DEVICE_FUNC inline void prefetch(const Scalar* a
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \internal \returns the first element of a packet */
|
||||||
|
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> 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> 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
|
||||||
|
predux_downto4(const Packet& a)
|
||||||
|
{ return a; }
|
||||||
|
|
||||||
|
/** \internal \returns the product of the elements of \a 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> 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> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_max(const Packet& a)
|
||||||
|
{ return a; }
|
||||||
|
|
||||||
/** \internal \returns the reversed elements of \a a*/
|
/** \internal \returns the reversed elements of \a a*/
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet preverse(const Packet& a)
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet preverse(const Packet& a)
|
||||||
{ return a; }
|
{ return a; }
|
||||||
@@ -740,7 +351,7 @@ template<typename Packet> EIGEN_DEVICE_FUNC inline Packet preverse(const Packet&
|
|||||||
/** \internal \returns \a a with real and imaginary part flipped (for complex type only) */
|
/** \internal \returns \a a with real and imaginary part flipped (for complex type only) */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet pcplxflip(const Packet& a)
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet pcplxflip(const Packet& a)
|
||||||
{
|
{
|
||||||
return Packet(numext::imag(a),numext::real(a));
|
return Packet(a.imag(),a.real());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************
|
/**************************
|
||||||
@@ -748,202 +359,84 @@ template<typename Packet> EIGEN_DEVICE_FUNC inline Packet pcplxflip(const Packet
|
|||||||
***************************/
|
***************************/
|
||||||
|
|
||||||
/** \internal \returns the sine of \a a (coeff-wise) */
|
/** \internal \returns the sine of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet psin(const Packet& a) { EIGEN_USING_STD(sin); return sin(a); }
|
Packet psin(const Packet& a) { using std::sin; return sin(a); }
|
||||||
|
|
||||||
/** \internal \returns the cosine of \a a (coeff-wise) */
|
/** \internal \returns the cosine of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet pcos(const Packet& a) { EIGEN_USING_STD(cos); return cos(a); }
|
Packet pcos(const Packet& a) { using std::cos; return cos(a); }
|
||||||
|
|
||||||
/** \internal \returns the tan of \a a (coeff-wise) */
|
/** \internal \returns the tan of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet ptan(const Packet& a) { EIGEN_USING_STD(tan); return tan(a); }
|
Packet ptan(const Packet& a) { using std::tan; return tan(a); }
|
||||||
|
|
||||||
/** \internal \returns the arc sine of \a a (coeff-wise) */
|
/** \internal \returns the arc sine of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet pasin(const Packet& a) { EIGEN_USING_STD(asin); return asin(a); }
|
Packet pasin(const Packet& a) { using std::asin; return asin(a); }
|
||||||
|
|
||||||
/** \internal \returns the arc cosine of \a a (coeff-wise) */
|
/** \internal \returns the arc cosine of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet pacos(const Packet& a) { EIGEN_USING_STD(acos); return acos(a); }
|
Packet pacos(const Packet& a) { using std::acos; return acos(a); }
|
||||||
|
|
||||||
/** \internal \returns the arc tangent of \a a (coeff-wise) */
|
/** \internal \returns the arc tangent of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet patan(const Packet& a) { EIGEN_USING_STD(atan); return atan(a); }
|
Packet patan(const Packet& a) { using std::atan; return atan(a); }
|
||||||
|
|
||||||
/** \internal \returns the hyperbolic sine of \a a (coeff-wise) */
|
/** \internal \returns the hyperbolic sine of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet psinh(const Packet& a) { EIGEN_USING_STD(sinh); return sinh(a); }
|
Packet psinh(const Packet& a) { using std::sinh; return sinh(a); }
|
||||||
|
|
||||||
/** \internal \returns the hyperbolic cosine of \a a (coeff-wise) */
|
/** \internal \returns the hyperbolic cosine of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet pcosh(const Packet& a) { EIGEN_USING_STD(cosh); return cosh(a); }
|
Packet pcosh(const Packet& a) { using std::cosh; return cosh(a); }
|
||||||
|
|
||||||
/** \internal \returns the hyperbolic tan of \a a (coeff-wise) */
|
/** \internal \returns the hyperbolic tan of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet ptanh(const Packet& a) { EIGEN_USING_STD(tanh); return tanh(a); }
|
Packet ptanh(const Packet& a) { using std::tanh; return tanh(a); }
|
||||||
|
|
||||||
/** \internal \returns the exp of \a a (coeff-wise) */
|
/** \internal \returns the exp of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet pexp(const Packet& a) { EIGEN_USING_STD(exp); return exp(a); }
|
Packet pexp(const Packet& a) { using std::exp; return exp(a); }
|
||||||
|
|
||||||
/** \internal \returns the expm1 of \a a (coeff-wise) */
|
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
|
||||||
Packet pexpm1(const Packet& a) { return numext::expm1(a); }
|
|
||||||
|
|
||||||
/** \internal \returns the log of \a a (coeff-wise) */
|
/** \internal \returns the log of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet plog(const Packet& a) { EIGEN_USING_STD(log); return log(a); }
|
Packet plog(const Packet& a) { using std::log; return log(a); }
|
||||||
|
|
||||||
/** \internal \returns the log1p of \a a (coeff-wise) */
|
/** \internal \returns the log1p of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet plog1p(const Packet& a) { return numext::log1p(a); }
|
Packet plog1p(const Packet& a) { return numext::log1p(a); }
|
||||||
|
|
||||||
/** \internal \returns the log10 of \a a (coeff-wise) */
|
/** \internal \returns the log10 of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet plog10(const Packet& a) { EIGEN_USING_STD(log10); return log10(a); }
|
Packet plog10(const Packet& a) { using std::log10; return log10(a); }
|
||||||
|
|
||||||
/** \internal \returns the log10 of \a a (coeff-wise) */
|
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
|
||||||
Packet plog2(const Packet& a) {
|
|
||||||
typedef typename internal::unpacket_traits<Packet>::type Scalar;
|
|
||||||
return pmul(pset1<Packet>(Scalar(EIGEN_LOG2E)), plog(a));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal \returns the square-root of \a a (coeff-wise) */
|
/** \internal \returns the square-root of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet psqrt(const Packet& a) { return numext::sqrt(a); }
|
Packet psqrt(const Packet& a) { using std::sqrt; return sqrt(a); }
|
||||||
|
|
||||||
/** \internal \returns the reciprocal square-root of \a a (coeff-wise) */
|
/** \internal \returns the reciprocal square-root of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet prsqrt(const Packet& a) {
|
Packet prsqrt(const Packet& a) {
|
||||||
typedef typename internal::unpacket_traits<Packet>::type Scalar;
|
return pdiv(pset1<Packet>(1), psqrt(a));
|
||||||
return pdiv(pset1<Packet>(Scalar(1)), psqrt(a));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \internal \returns the rounded value of \a a (coeff-wise) */
|
/** \internal \returns the rounded value of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet pround(const Packet& a) { using numext::round; return round(a); }
|
Packet pround(const Packet& a) { using numext::round; return round(a); }
|
||||||
|
|
||||||
/** \internal \returns the floor of \a a (coeff-wise) */
|
/** \internal \returns the floor of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet pfloor(const Packet& a) { using numext::floor; return floor(a); }
|
Packet pfloor(const Packet& a) { using numext::floor; return floor(a); }
|
||||||
|
|
||||||
/** \internal \returns the rounded value of \a a (coeff-wise) with current
|
|
||||||
* rounding mode */
|
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
|
||||||
Packet print(const Packet& a) { using numext::rint; return rint(a); }
|
|
||||||
|
|
||||||
/** \internal \returns the ceil of \a a (coeff-wise) */
|
/** \internal \returns the ceil of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet pceil(const Packet& a) { using numext::ceil; return ceil(a); }
|
Packet pceil(const Packet& a) { using numext::ceil; return ceil(a); }
|
||||||
|
|
||||||
/** \internal \returns the first element of a packet */
|
|
||||||
template<typename Packet>
|
|
||||||
EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type
|
|
||||||
pfirst(const Packet& a)
|
|
||||||
{ return a; }
|
|
||||||
|
|
||||||
/** \internal \returns the sum of the elements of upper and lower half of \a a if \a a is larger than 4.
|
|
||||||
* 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
|
|
||||||
predux_half_dowto4(const Packet& a)
|
|
||||||
{ return a; }
|
|
||||||
|
|
||||||
// Slow generic implementation of Packet reduction.
|
|
||||||
template <typename Packet, typename Op>
|
|
||||||
EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type
|
|
||||||
predux_helper(const Packet& a, Op op) {
|
|
||||||
typedef typename unpacket_traits<Packet>::type Scalar;
|
|
||||||
const size_t n = unpacket_traits<Packet>::size;
|
|
||||||
EIGEN_ALIGN_TO_BOUNDARY(sizeof(Packet)) Scalar elements[n];
|
|
||||||
pstoreu<Scalar>(elements, a);
|
|
||||||
for(size_t k = n / 2; k > 0; k /= 2) {
|
|
||||||
for(size_t i = 0; i < k; ++i) {
|
|
||||||
elements[i] = op(elements[i], elements[i + k]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return elements[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal \returns the sum of the elements of \a a*/
|
|
||||||
template<typename Packet>
|
|
||||||
EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type
|
|
||||||
predux(const Packet& a)
|
|
||||||
{
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal \returns the product of the elements of \a a */
|
|
||||||
template <typename Packet>
|
|
||||||
EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_mul(
|
|
||||||
const Packet& a) {
|
|
||||||
typedef typename unpacket_traits<Packet>::type Scalar;
|
|
||||||
return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmul<Scalar>)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal \returns the min of the elements of \a a */
|
|
||||||
template <typename Packet>
|
|
||||||
EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_min(
|
|
||||||
const Packet &a) {
|
|
||||||
typedef typename unpacket_traits<Packet>::type Scalar;
|
|
||||||
return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmin<PropagateFast, Scalar>)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <int NaNPropagation, typename Packet>
|
|
||||||
EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_min(
|
|
||||||
const Packet& a) {
|
|
||||||
typedef typename unpacket_traits<Packet>::type Scalar;
|
|
||||||
return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmin<NaNPropagation, Scalar>)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal \returns the min of the elements of \a a */
|
|
||||||
template <typename Packet>
|
|
||||||
EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_max(
|
|
||||||
const Packet &a) {
|
|
||||||
typedef typename unpacket_traits<Packet>::type Scalar;
|
|
||||||
return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmax<PropagateFast, Scalar>)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <int NaNPropagation, typename Packet>
|
|
||||||
EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_max(
|
|
||||||
const Packet& a) {
|
|
||||||
typedef typename unpacket_traits<Packet>::type Scalar;
|
|
||||||
return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmax<NaNPropagation, Scalar>)));
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef EIGEN_BINARY_OP_NAN_PROPAGATION
|
|
||||||
|
|
||||||
/** \internal \returns true if all coeffs of \a a means "true"
|
|
||||||
* It is supposed to be called on values returned by pcmp_*.
|
|
||||||
*/
|
|
||||||
// not needed yet
|
|
||||||
// template<typename Packet> EIGEN_DEVICE_FUNC inline bool predux_all(const Packet& a)
|
|
||||||
// { return bool(a); }
|
|
||||||
|
|
||||||
/** \internal \returns true if any coeffs of \a a means "true"
|
|
||||||
* It is supposed to be called on values returned by pcmp_*.
|
|
||||||
*/
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline bool predux_any(const Packet& a)
|
|
||||||
{
|
|
||||||
// Dirty but generic implementation where "true" is assumed to be non 0 and all the sames.
|
|
||||||
// It is expected that "true" is either:
|
|
||||||
// - Scalar(1)
|
|
||||||
// - bits full of ones (NaN for floats),
|
|
||||||
// - or first bit equals to 1 (1 for ints, smallest denormal for floats).
|
|
||||||
// For all these cases, taking the sum is just fine, and this boils down to a no-op for scalars.
|
|
||||||
typedef typename unpacket_traits<Packet>::type Scalar;
|
|
||||||
return numext::not_equal_strict(predux(a), Scalar(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* The following functions might not have to be overwritten for vectorized types
|
* The following functions might not have to be overwritten for vectorized types
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
/** \internal copy a packet with constant coefficient \a a (e.g., [a,a,a,a]) to \a *to. \a to must be 16 bytes aligned */
|
/** \internal copy a packet with constant coeficient \a a (e.g., [a,a,a,a]) to \a *to. \a to must be 16 bytes aligned */
|
||||||
// NOTE: this function must really be templated on the packet type (think about different packet types for the same scalar type)
|
// NOTE: this function must really be templated on the packet type (think about different packet types for the same scalar type)
|
||||||
template<typename Packet>
|
template<typename Packet>
|
||||||
inline void pstore1(typename unpacket_traits<Packet>::type* to, const typename unpacket_traits<Packet>::type& a)
|
inline void pstore1(typename unpacket_traits<Packet>::type* to, const typename unpacket_traits<Packet>::type& a)
|
||||||
@@ -991,12 +484,41 @@ EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet ploadt_ro(const typename unpacket_t
|
|||||||
return ploadt<Packet, LoadMode>(from);
|
return ploadt<Packet, LoadMode>(from);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \internal default implementation of palign() allowing partial specialization */
|
||||||
|
template<int Offset,typename PacketType>
|
||||||
|
struct palign_impl
|
||||||
|
{
|
||||||
|
// by default data are aligned, so there is nothing to be done :)
|
||||||
|
static inline void run(PacketType&, const PacketType&) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** \internal update \a first using the concatenation of the packet_size minus \a Offset last elements
|
||||||
|
* of \a first and \a Offset first elements of \a second.
|
||||||
|
*
|
||||||
|
* This function is currently only used to optimize matrix-vector products on unligned matrices.
|
||||||
|
* It takes 2 packets that represent a contiguous memory array, and returns a packet starting
|
||||||
|
* at the position \a Offset. For instance, for packets of 4 elements, we have:
|
||||||
|
* Input:
|
||||||
|
* - first = {f0,f1,f2,f3}
|
||||||
|
* - second = {s0,s1,s2,s3}
|
||||||
|
* Output:
|
||||||
|
* - if Offset==0 then {f0,f1,f2,f3}
|
||||||
|
* - if Offset==1 then {f1,f2,f3,s0}
|
||||||
|
* - if Offset==2 then {f2,f3,s0,s1}
|
||||||
|
* - if Offset==3 then {f3,s0,s1,s3}
|
||||||
|
*/
|
||||||
|
template<int Offset,typename PacketType>
|
||||||
|
inline void palign(PacketType& first, const PacketType& second)
|
||||||
|
{
|
||||||
|
palign_impl<Offset,PacketType>::run(first,second);
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Fast complex products (GCC generates a function call which is very slow)
|
* Fast complex products (GCC generates a function call which is very slow)
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
// Eigen+CUDA does not support complexes.
|
// Eigen+CUDA does not support complexes.
|
||||||
#if !defined(EIGEN_GPUCC)
|
#ifndef EIGEN_CUDACC
|
||||||
|
|
||||||
template<> inline std::complex<float> pmul(const std::complex<float>& a, const std::complex<float>& b)
|
template<> inline std::complex<float> pmul(const std::complex<float>& a, const std::complex<float>& b)
|
||||||
{ return std::complex<float>(a.real()*b.real() - a.imag()*b.imag(), a.imag()*b.real() + a.real()*b.imag()); }
|
{ return std::complex<float>(a.real()*b.real() - a.imag()*b.imag(), a.imag()*b.real() + a.real()*b.imag()); }
|
||||||
@@ -1033,6 +555,34 @@ pblend(const Selector<unpacket_traits<Packet>::size>& ifPacket, const Packet& th
|
|||||||
return ifPacket.select[0] ? thenPacket : elsePacket;
|
return ifPacket.select[0] ? thenPacket : elsePacket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \internal \returns \a a with the first coefficient replaced by the scalar b */
|
||||||
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
|
pinsertfirst(const Packet& a, typename unpacket_traits<Packet>::type b)
|
||||||
|
{
|
||||||
|
// Default implementation based on pblend.
|
||||||
|
// It must be specialized for higher performance.
|
||||||
|
Selector<unpacket_traits<Packet>::size> mask;
|
||||||
|
mask.select[0] = true;
|
||||||
|
// This for loop should be optimized away by the compiler.
|
||||||
|
for(Index i=1; i<unpacket_traits<Packet>::size; ++i)
|
||||||
|
mask.select[i] = false;
|
||||||
|
return pblend(mask, pset1<Packet>(b), a);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \internal \returns \a a with the last coefficient replaced by the scalar b */
|
||||||
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
|
pinsertlast(const Packet& a, typename unpacket_traits<Packet>::type b)
|
||||||
|
{
|
||||||
|
// Default implementation based on pblend.
|
||||||
|
// It must be specialized for higher performance.
|
||||||
|
Selector<unpacket_traits<Packet>::size> mask;
|
||||||
|
// This for loop should be optimized away by the compiler.
|
||||||
|
for(Index i=0; i<unpacket_traits<Packet>::size-1; ++i)
|
||||||
|
mask.select[i] = false;
|
||||||
|
mask.select[unpacket_traits<Packet>::size-1] = true;
|
||||||
|
return pblend(mask, pset1<Packet>(b), a);
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|||||||
@@ -66,31 +66,21 @@ namespace Eigen
|
|||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sinh,scalar_sinh_op,hyperbolic sine,\sa ArrayBase::sinh)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sinh,scalar_sinh_op,hyperbolic sine,\sa ArrayBase::sinh)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cosh,scalar_cosh_op,hyperbolic cosine,\sa ArrayBase::cosh)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cosh,scalar_cosh_op,hyperbolic cosine,\sa ArrayBase::cosh)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(tanh,scalar_tanh_op,hyperbolic tangent,\sa ArrayBase::tanh)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(tanh,scalar_tanh_op,hyperbolic tangent,\sa ArrayBase::tanh)
|
||||||
#if EIGEN_HAS_CXX11_MATH
|
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(asinh,scalar_asinh_op,inverse hyperbolic sine,\sa ArrayBase::asinh)
|
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(acosh,scalar_acosh_op,inverse hyperbolic cosine,\sa ArrayBase::acosh)
|
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(atanh,scalar_atanh_op,inverse hyperbolic tangent,\sa ArrayBase::atanh)
|
|
||||||
#endif
|
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(logistic,scalar_logistic_op,logistic function,\sa ArrayBase::logistic)
|
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(lgamma,scalar_lgamma_op,natural logarithm of the gamma function,\sa ArrayBase::lgamma)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(lgamma,scalar_lgamma_op,natural logarithm of the gamma function,\sa ArrayBase::lgamma)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(digamma,scalar_digamma_op,derivative of lgamma,\sa ArrayBase::digamma)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(digamma,scalar_digamma_op,derivative of lgamma,\sa ArrayBase::digamma)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(erf,scalar_erf_op,error function,\sa ArrayBase::erf)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(erf,scalar_erf_op,error function,\sa ArrayBase::erf)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(erfc,scalar_erfc_op,complement error function,\sa ArrayBase::erfc)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(erfc,scalar_erfc_op,complement error function,\sa ArrayBase::erfc)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(ndtri,scalar_ndtri_op,inverse normal distribution function,\sa ArrayBase::ndtri)
|
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(exp,scalar_exp_op,exponential,\sa ArrayBase::exp)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(exp,scalar_exp_op,exponential,\sa ArrayBase::exp)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(expm1,scalar_expm1_op,exponential of a value minus 1,\sa ArrayBase::expm1)
|
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log,scalar_log_op,natural logarithm,\sa Eigen::log10 DOXCOMMA ArrayBase::log)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log,scalar_log_op,natural logarithm,\sa Eigen::log10 DOXCOMMA ArrayBase::log)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log1p,scalar_log1p_op,natural logarithm of 1 plus the value,\sa ArrayBase::log1p)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log1p,scalar_log1p_op,natural logarithm of 1 plus the value,\sa ArrayBase::log1p)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log10,scalar_log10_op,base 10 logarithm,\sa Eigen::log DOXCOMMA ArrayBase::log10)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log10,scalar_log10_op,base 10 logarithm,\sa Eigen::log DOXCOMMA ArrayBase::log)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log2,scalar_log2_op,base 2 logarithm,\sa Eigen::log DOXCOMMA ArrayBase::log2)
|
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(abs,scalar_abs_op,absolute value,\sa ArrayBase::abs DOXCOMMA MatrixBase::cwiseAbs)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(abs,scalar_abs_op,absolute value,\sa ArrayBase::abs DOXCOMMA MatrixBase::cwiseAbs)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(abs2,scalar_abs2_op,squared absolute value,\sa ArrayBase::abs2 DOXCOMMA MatrixBase::cwiseAbs2)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(abs2,scalar_abs2_op,squared absolute value,\sa ArrayBase::abs2 DOXCOMMA MatrixBase::cwiseAbs2)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(arg,scalar_arg_op,complex argument,\sa ArrayBase::arg DOXCOMMA MatrixBase::cwiseArg)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(arg,scalar_arg_op,complex argument,\sa ArrayBase::arg)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sqrt,scalar_sqrt_op,square root,\sa ArrayBase::sqrt DOXCOMMA MatrixBase::cwiseSqrt)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sqrt,scalar_sqrt_op,square root,\sa ArrayBase::sqrt DOXCOMMA MatrixBase::cwiseSqrt)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(rsqrt,scalar_rsqrt_op,reciprocal square root,\sa ArrayBase::rsqrt)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(rsqrt,scalar_rsqrt_op,reciprocal square root,\sa ArrayBase::rsqrt)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(square,scalar_square_op,square (power 2),\sa Eigen::abs2 DOXCOMMA Eigen::pow DOXCOMMA ArrayBase::square)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(square,scalar_square_op,square (power 2),\sa Eigen::abs2 DOXCOMMA Eigen::pow DOXCOMMA ArrayBase::square)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cube,scalar_cube_op,cube (power 3),\sa Eigen::pow DOXCOMMA ArrayBase::cube)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cube,scalar_cube_op,cube (power 3),\sa Eigen::pow DOXCOMMA ArrayBase::cube)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(rint,scalar_rint_op,nearest integer,\sa Eigen::floor DOXCOMMA Eigen::ceil DOXCOMMA ArrayBase::round)
|
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(round,scalar_round_op,nearest integer,\sa Eigen::floor DOXCOMMA Eigen::ceil DOXCOMMA ArrayBase::round)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(round,scalar_round_op,nearest integer,\sa Eigen::floor DOXCOMMA Eigen::ceil DOXCOMMA ArrayBase::round)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(floor,scalar_floor_op,nearest integer not greater than the giben value,\sa Eigen::ceil DOXCOMMA ArrayBase::floor)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(floor,scalar_floor_op,nearest integer not greater than the giben value,\sa Eigen::ceil DOXCOMMA ArrayBase::floor)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(ceil,scalar_ceil_op,nearest integer not less than the giben value,\sa Eigen::floor DOXCOMMA ArrayBase::ceil)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(ceil,scalar_ceil_op,nearest integer not less than the giben value,\sa Eigen::floor DOXCOMMA ArrayBase::ceil)
|
||||||
@@ -112,18 +102,17 @@ namespace Eigen
|
|||||||
inline const CwiseBinaryOp<internal::scalar_pow_op<Derived::Scalar,ScalarExponent>,Derived,Constant<ScalarExponent> >
|
inline const CwiseBinaryOp<internal::scalar_pow_op<Derived::Scalar,ScalarExponent>,Derived,Constant<ScalarExponent> >
|
||||||
pow(const Eigen::ArrayBase<Derived>& x, const ScalarExponent& exponent);
|
pow(const Eigen::ArrayBase<Derived>& x, const ScalarExponent& exponent);
|
||||||
#else
|
#else
|
||||||
template <typename Derived,typename ScalarExponent>
|
template<typename Derived,typename ScalarExponent>
|
||||||
EIGEN_DEVICE_FUNC inline
|
inline typename internal::enable_if< !(internal::is_same<typename Derived::Scalar,ScalarExponent>::value) && EIGEN_SCALAR_BINARY_SUPPORTED(pow,typename Derived::Scalar,ScalarExponent),
|
||||||
EIGEN_MSVC10_WORKAROUND_BINARYOP_RETURN_TYPE(
|
const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(Derived,ScalarExponent,pow) >::type
|
||||||
const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(Derived,typename internal::promote_scalar_arg<typename Derived::Scalar
|
pow(const Eigen::ArrayBase<Derived>& x, const ScalarExponent& exponent) {
|
||||||
EIGEN_COMMA ScalarExponent EIGEN_COMMA
|
return x.derived().pow(exponent);
|
||||||
EIGEN_SCALAR_BINARY_SUPPORTED(pow,typename Derived::Scalar,ScalarExponent)>::type,pow))
|
}
|
||||||
pow(const Eigen::ArrayBase<Derived>& x, const ScalarExponent& exponent)
|
|
||||||
{
|
template<typename Derived>
|
||||||
typedef typename internal::promote_scalar_arg<typename Derived::Scalar,ScalarExponent,
|
inline const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(Derived,typename Derived::Scalar,pow)
|
||||||
EIGEN_SCALAR_BINARY_SUPPORTED(pow,typename Derived::Scalar,ScalarExponent)>::type PromotedExponent;
|
pow(const Eigen::ArrayBase<Derived>& x, const typename Derived::Scalar& exponent) {
|
||||||
return EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(Derived,PromotedExponent,pow)(x.derived(),
|
return x.derived().pow(exponent);
|
||||||
typename internal::plain_constant_type<Derived,PromotedExponent>::type(x.derived().rows(), x.derived().cols(), internal::scalar_constant_op<PromotedExponent>(exponent)));
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -166,17 +155,21 @@ namespace Eigen
|
|||||||
inline const CwiseBinaryOp<internal::scalar_pow_op<Scalar,Derived::Scalar>,Constant<Scalar>,Derived>
|
inline const CwiseBinaryOp<internal::scalar_pow_op<Scalar,Derived::Scalar>,Constant<Scalar>,Derived>
|
||||||
pow(const Scalar& x,const Eigen::ArrayBase<Derived>& x);
|
pow(const Scalar& x,const Eigen::ArrayBase<Derived>& x);
|
||||||
#else
|
#else
|
||||||
template <typename Scalar, typename Derived>
|
template<typename Scalar, typename Derived>
|
||||||
EIGEN_DEVICE_FUNC inline
|
inline typename internal::enable_if< !(internal::is_same<typename Derived::Scalar,Scalar>::value) && EIGEN_SCALAR_BINARY_SUPPORTED(pow,Scalar,typename Derived::Scalar),
|
||||||
EIGEN_MSVC10_WORKAROUND_BINARYOP_RETURN_TYPE(
|
const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar,Derived,pow) >::type
|
||||||
const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(typename internal::promote_scalar_arg<typename Derived::Scalar
|
pow(const Scalar& x, const Eigen::ArrayBase<Derived>& exponents)
|
||||||
EIGEN_COMMA Scalar EIGEN_COMMA
|
{
|
||||||
EIGEN_SCALAR_BINARY_SUPPORTED(pow,Scalar,typename Derived::Scalar)>::type,Derived,pow))
|
return EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar,Derived,pow)(
|
||||||
pow(const Scalar& x, const Eigen::ArrayBase<Derived>& exponents) {
|
typename internal::plain_constant_type<Derived,Scalar>::type(exponents.rows(), exponents.cols(), x), exponents.derived() );
|
||||||
typedef typename internal::promote_scalar_arg<typename Derived::Scalar,Scalar,
|
}
|
||||||
EIGEN_SCALAR_BINARY_SUPPORTED(pow,Scalar,typename Derived::Scalar)>::type PromotedScalar;
|
|
||||||
return EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(PromotedScalar,Derived,pow)(
|
template<typename Derived>
|
||||||
typename internal::plain_constant_type<Derived,PromotedScalar>::type(exponents.derived().rows(), exponents.derived().cols(), internal::scalar_constant_op<PromotedScalar>(x)), exponents.derived());
|
inline const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(typename Derived::Scalar,Derived,pow)
|
||||||
|
pow(const typename Derived::Scalar& x, const Eigen::ArrayBase<Derived>& exponents)
|
||||||
|
{
|
||||||
|
return EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(typename Derived::Scalar,Derived,pow)(
|
||||||
|
typename internal::plain_constant_type<Derived,typename Derived::Scalar>::type(exponents.rows(), exponents.cols(), x), exponents.derived() );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat&
|
|||||||
* - \b rowSuffix string printed at the end of each row
|
* - \b rowSuffix string printed at the end of each row
|
||||||
* - \b matPrefix string printed at the beginning of the matrix
|
* - \b matPrefix string printed at the beginning of the matrix
|
||||||
* - \b matSuffix string printed at the end of the matrix
|
* - \b matSuffix string printed at the end of the matrix
|
||||||
* - \b fill character printed to fill the empty space in aligned columns
|
|
||||||
*
|
*
|
||||||
* Example: \include IOFormat.cpp
|
* Example: \include IOFormat.cpp
|
||||||
* Output: \verbinclude IOFormat.out
|
* Output: \verbinclude IOFormat.out
|
||||||
@@ -54,9 +53,9 @@ struct IOFormat
|
|||||||
IOFormat(int _precision = StreamPrecision, int _flags = 0,
|
IOFormat(int _precision = StreamPrecision, int _flags = 0,
|
||||||
const std::string& _coeffSeparator = " ",
|
const std::string& _coeffSeparator = " ",
|
||||||
const std::string& _rowSeparator = "\n", const std::string& _rowPrefix="", const std::string& _rowSuffix="",
|
const std::string& _rowSeparator = "\n", const std::string& _rowPrefix="", const std::string& _rowSuffix="",
|
||||||
const std::string& _matPrefix="", const std::string& _matSuffix="", const char _fill=' ')
|
const std::string& _matPrefix="", const std::string& _matSuffix="")
|
||||||
: matPrefix(_matPrefix), matSuffix(_matSuffix), rowPrefix(_rowPrefix), rowSuffix(_rowSuffix), rowSeparator(_rowSeparator),
|
: matPrefix(_matPrefix), matSuffix(_matSuffix), rowPrefix(_rowPrefix), rowSuffix(_rowSuffix), rowSeparator(_rowSeparator),
|
||||||
rowSpacer(""), coeffSeparator(_coeffSeparator), fill(_fill), precision(_precision), flags(_flags)
|
rowSpacer(""), coeffSeparator(_coeffSeparator), precision(_precision), flags(_flags)
|
||||||
{
|
{
|
||||||
// TODO check if rowPrefix, rowSuffix or rowSeparator contains a newline
|
// TODO check if rowPrefix, rowSuffix or rowSeparator contains a newline
|
||||||
// don't add rowSpacer if columns are not to be aligned
|
// don't add rowSpacer if columns are not to be aligned
|
||||||
@@ -72,7 +71,6 @@ struct IOFormat
|
|||||||
std::string matPrefix, matSuffix;
|
std::string matPrefix, matSuffix;
|
||||||
std::string rowPrefix, rowSuffix, rowSeparator, rowSpacer;
|
std::string rowPrefix, rowSuffix, rowSeparator, rowSpacer;
|
||||||
std::string coeffSeparator;
|
std::string coeffSeparator;
|
||||||
char fill;
|
|
||||||
int precision;
|
int precision;
|
||||||
int flags;
|
int flags;
|
||||||
};
|
};
|
||||||
@@ -130,9 +128,6 @@ struct significant_decimals_impl
|
|||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt)
|
std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt)
|
||||||
{
|
{
|
||||||
using internal::is_same;
|
|
||||||
using internal::conditional;
|
|
||||||
|
|
||||||
if(_m.size() == 0)
|
if(_m.size() == 0)
|
||||||
{
|
{
|
||||||
s << fmt.matPrefix << fmt.matSuffix;
|
s << fmt.matPrefix << fmt.matSuffix;
|
||||||
@@ -141,22 +136,6 @@ std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat&
|
|||||||
|
|
||||||
typename Derived::Nested m = _m;
|
typename Derived::Nested m = _m;
|
||||||
typedef typename Derived::Scalar Scalar;
|
typedef typename Derived::Scalar Scalar;
|
||||||
typedef typename
|
|
||||||
conditional<
|
|
||||||
is_same<Scalar, char>::value ||
|
|
||||||
is_same<Scalar, unsigned char>::value ||
|
|
||||||
is_same<Scalar, numext::int8_t>::value ||
|
|
||||||
is_same<Scalar, numext::uint8_t>::value,
|
|
||||||
int,
|
|
||||||
typename conditional<
|
|
||||||
is_same<Scalar, std::complex<char> >::value ||
|
|
||||||
is_same<Scalar, std::complex<unsigned char> >::value ||
|
|
||||||
is_same<Scalar, std::complex<numext::int8_t> >::value ||
|
|
||||||
is_same<Scalar, std::complex<numext::uint8_t> >::value,
|
|
||||||
std::complex<int>,
|
|
||||||
const Scalar&
|
|
||||||
>::type
|
|
||||||
>::type PrintType;
|
|
||||||
|
|
||||||
Index width = 0;
|
Index width = 0;
|
||||||
|
|
||||||
@@ -193,31 +172,23 @@ std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat&
|
|||||||
{
|
{
|
||||||
std::stringstream sstr;
|
std::stringstream sstr;
|
||||||
sstr.copyfmt(s);
|
sstr.copyfmt(s);
|
||||||
sstr << static_cast<PrintType>(m.coeff(i,j));
|
sstr << m.coeff(i,j);
|
||||||
width = std::max<Index>(width, Index(sstr.str().length()));
|
width = std::max<Index>(width, Index(sstr.str().length()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::streamsize old_width = s.width();
|
|
||||||
char old_fill_character = s.fill();
|
|
||||||
s << fmt.matPrefix;
|
s << fmt.matPrefix;
|
||||||
for(Index i = 0; i < m.rows(); ++i)
|
for(Index i = 0; i < m.rows(); ++i)
|
||||||
{
|
{
|
||||||
if (i)
|
if (i)
|
||||||
s << fmt.rowSpacer;
|
s << fmt.rowSpacer;
|
||||||
s << fmt.rowPrefix;
|
s << fmt.rowPrefix;
|
||||||
if(width) {
|
if(width) s.width(width);
|
||||||
s.fill(fmt.fill);
|
s << m.coeff(i, 0);
|
||||||
s.width(width);
|
|
||||||
}
|
|
||||||
s << static_cast<PrintType>(m.coeff(i, 0));
|
|
||||||
for(Index j = 1; j < m.cols(); ++j)
|
for(Index j = 1; j < m.cols(); ++j)
|
||||||
{
|
{
|
||||||
s << fmt.coeffSeparator;
|
s << fmt.coeffSeparator;
|
||||||
if(width) {
|
if (width) s.width(width);
|
||||||
s.fill(fmt.fill);
|
s << m.coeff(i, j);
|
||||||
s.width(width);
|
|
||||||
}
|
|
||||||
s << static_cast<PrintType>(m.coeff(i, j));
|
|
||||||
}
|
}
|
||||||
s << fmt.rowSuffix;
|
s << fmt.rowSuffix;
|
||||||
if( i < m.rows() - 1)
|
if( i < m.rows() - 1)
|
||||||
@@ -225,10 +196,6 @@ std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat&
|
|||||||
}
|
}
|
||||||
s << fmt.matSuffix;
|
s << fmt.matSuffix;
|
||||||
if(explicit_precision) s.precision(old_precision);
|
if(explicit_precision) s.precision(old_precision);
|
||||||
if(width) {
|
|
||||||
s.fill(old_fill_character);
|
|
||||||
s.width(old_width);
|
|
||||||
}
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,247 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2017 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_INDEXED_VIEW_H
|
|
||||||
#define EIGEN_INDEXED_VIEW_H
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template<typename XprType, typename RowIndices, typename ColIndices>
|
|
||||||
struct traits<IndexedView<XprType, RowIndices, ColIndices> >
|
|
||||||
: traits<XprType>
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
RowsAtCompileTime = int(array_size<RowIndices>::value),
|
|
||||||
ColsAtCompileTime = int(array_size<ColIndices>::value),
|
|
||||||
MaxRowsAtCompileTime = RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime) : Dynamic,
|
|
||||||
MaxColsAtCompileTime = ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime) : Dynamic,
|
|
||||||
|
|
||||||
XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0,
|
|
||||||
IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1
|
|
||||||
: (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
|
|
||||||
: XprTypeIsRowMajor,
|
|
||||||
|
|
||||||
RowIncr = int(get_compile_time_incr<RowIndices>::value),
|
|
||||||
ColIncr = int(get_compile_time_incr<ColIndices>::value),
|
|
||||||
InnerIncr = IsRowMajor ? ColIncr : RowIncr,
|
|
||||||
OuterIncr = IsRowMajor ? RowIncr : ColIncr,
|
|
||||||
|
|
||||||
HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor),
|
|
||||||
XprInnerStride = HasSameStorageOrderAsXprType ? int(inner_stride_at_compile_time<XprType>::ret) : int(outer_stride_at_compile_time<XprType>::ret),
|
|
||||||
XprOuterstride = HasSameStorageOrderAsXprType ? int(outer_stride_at_compile_time<XprType>::ret) : int(inner_stride_at_compile_time<XprType>::ret),
|
|
||||||
|
|
||||||
InnerSize = XprTypeIsRowMajor ? ColsAtCompileTime : RowsAtCompileTime,
|
|
||||||
IsBlockAlike = InnerIncr==1 && OuterIncr==1,
|
|
||||||
IsInnerPannel = HasSameStorageOrderAsXprType && is_same<AllRange<InnerSize>,typename conditional<XprTypeIsRowMajor,ColIndices,RowIndices>::type>::value,
|
|
||||||
|
|
||||||
InnerStrideAtCompileTime = InnerIncr<0 || InnerIncr==DynamicIndex || XprInnerStride==Dynamic ? Dynamic : XprInnerStride * InnerIncr,
|
|
||||||
OuterStrideAtCompileTime = OuterIncr<0 || OuterIncr==DynamicIndex || XprOuterstride==Dynamic ? Dynamic : XprOuterstride * OuterIncr,
|
|
||||||
|
|
||||||
ReturnAsScalar = is_same<RowIndices,SingleRange>::value && is_same<ColIndices,SingleRange>::value,
|
|
||||||
ReturnAsBlock = (!ReturnAsScalar) && IsBlockAlike,
|
|
||||||
ReturnAsIndexedView = (!ReturnAsScalar) && (!ReturnAsBlock),
|
|
||||||
|
|
||||||
// FIXME we deal with compile-time strides if and only if we have DirectAccessBit flag,
|
|
||||||
// but this is too strict regarding negative strides...
|
|
||||||
DirectAccessMask = (int(InnerIncr)!=UndefinedIncr && int(OuterIncr)!=UndefinedIncr && InnerIncr>=0 && OuterIncr>=0) ? DirectAccessBit : 0,
|
|
||||||
FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
|
|
||||||
FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
|
|
||||||
FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0,
|
|
||||||
Flags = (traits<XprType>::Flags & (HereditaryBits | DirectAccessMask )) | FlagsLvalueBit | FlagsRowMajorBit | FlagsLinearAccessBit
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef Block<XprType,RowsAtCompileTime,ColsAtCompileTime,IsInnerPannel> BlockType;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename XprType, typename RowIndices, typename ColIndices, typename StorageKind>
|
|
||||||
class IndexedViewImpl;
|
|
||||||
|
|
||||||
|
|
||||||
/** \class IndexedView
|
|
||||||
* \ingroup Core_Module
|
|
||||||
*
|
|
||||||
* \brief Expression of a non-sequential sub-matrix defined by arbitrary sequences of row and column indices
|
|
||||||
*
|
|
||||||
* \tparam XprType the type of the expression in which we are taking the intersections of sub-rows and sub-columns
|
|
||||||
* \tparam RowIndices the type of the object defining the sequence of row indices
|
|
||||||
* \tparam ColIndices the type of the object defining the sequence of column indices
|
|
||||||
*
|
|
||||||
* This class represents an expression of a sub-matrix (or sub-vector) defined as the intersection
|
|
||||||
* of sub-sets of rows and columns, that are themself defined by generic sequences of row indices \f$ \{r_0,r_1,..r_{m-1}\} \f$
|
|
||||||
* and column indices \f$ \{c_0,c_1,..c_{n-1} \}\f$. Let \f$ A \f$ be the nested matrix, then the resulting matrix \f$ B \f$ has \c m
|
|
||||||
* rows and \c n columns, and its entries are given by: \f$ B(i,j) = A(r_i,c_j) \f$.
|
|
||||||
*
|
|
||||||
* The \c RowIndices and \c ColIndices types must be compatible with the following API:
|
|
||||||
* \code
|
|
||||||
* <integral type> operator[](Index) const;
|
|
||||||
* Index size() const;
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* Typical supported types thus include:
|
|
||||||
* - std::vector<int>
|
|
||||||
* - std::valarray<int>
|
|
||||||
* - std::array<int>
|
|
||||||
* - Plain C arrays: int[N]
|
|
||||||
* - Eigen::ArrayXi
|
|
||||||
* - decltype(ArrayXi::LinSpaced(...))
|
|
||||||
* - Any view/expressions of the previous types
|
|
||||||
* - Eigen::ArithmeticSequence
|
|
||||||
* - Eigen::internal::AllRange (helper for Eigen::all)
|
|
||||||
* - Eigen::internal::SingleRange (helper for single index)
|
|
||||||
* - etc.
|
|
||||||
*
|
|
||||||
* In typical usages of %Eigen, this class should never be used directly. It is the return type of
|
|
||||||
* DenseBase::operator()(const RowIndices&, const ColIndices&).
|
|
||||||
*
|
|
||||||
* \sa class Block
|
|
||||||
*/
|
|
||||||
template<typename XprType, typename RowIndices, typename ColIndices>
|
|
||||||
class IndexedView : public IndexedViewImpl<XprType, RowIndices, ColIndices, typename internal::traits<XprType>::StorageKind>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef typename IndexedViewImpl<XprType, RowIndices, ColIndices, typename internal::traits<XprType>::StorageKind>::Base Base;
|
|
||||||
EIGEN_GENERIC_PUBLIC_INTERFACE(IndexedView)
|
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(IndexedView)
|
|
||||||
|
|
||||||
typedef typename internal::ref_selector<XprType>::non_const_type MatrixTypeNested;
|
|
||||||
typedef typename internal::remove_all<XprType>::type NestedExpression;
|
|
||||||
|
|
||||||
template<typename T0, typename T1>
|
|
||||||
IndexedView(XprType& xpr, const T0& rowIndices, const T1& colIndices)
|
|
||||||
: m_xpr(xpr), m_rowIndices(rowIndices), m_colIndices(colIndices)
|
|
||||||
{}
|
|
||||||
|
|
||||||
/** \returns number of rows */
|
|
||||||
Index rows() const { return internal::index_list_size(m_rowIndices); }
|
|
||||||
|
|
||||||
/** \returns number of columns */
|
|
||||||
Index cols() const { return internal::index_list_size(m_colIndices); }
|
|
||||||
|
|
||||||
/** \returns the nested expression */
|
|
||||||
const typename internal::remove_all<XprType>::type&
|
|
||||||
nestedExpression() const { return m_xpr; }
|
|
||||||
|
|
||||||
/** \returns the nested expression */
|
|
||||||
typename internal::remove_reference<XprType>::type&
|
|
||||||
nestedExpression() { return m_xpr; }
|
|
||||||
|
|
||||||
/** \returns a const reference to the object storing/generating the row indices */
|
|
||||||
const RowIndices& rowIndices() const { return m_rowIndices; }
|
|
||||||
|
|
||||||
/** \returns a const reference to the object storing/generating the column indices */
|
|
||||||
const ColIndices& colIndices() const { return m_colIndices; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
MatrixTypeNested m_xpr;
|
|
||||||
RowIndices m_rowIndices;
|
|
||||||
ColIndices m_colIndices;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Generic API dispatcher
|
|
||||||
template<typename XprType, typename RowIndices, typename ColIndices, typename StorageKind>
|
|
||||||
class IndexedViewImpl
|
|
||||||
: public internal::generic_xpr_base<IndexedView<XprType, RowIndices, ColIndices> >::type
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef typename internal::generic_xpr_base<IndexedView<XprType, RowIndices, ColIndices> >::type Base;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
|
|
||||||
template<typename ArgType, typename RowIndices, typename ColIndices>
|
|
||||||
struct unary_evaluator<IndexedView<ArgType, RowIndices, ColIndices>, IndexBased>
|
|
||||||
: evaluator_base<IndexedView<ArgType, RowIndices, ColIndices> >
|
|
||||||
{
|
|
||||||
typedef IndexedView<ArgType, RowIndices, ColIndices> XprType;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
CoeffReadCost = evaluator<ArgType>::CoeffReadCost /* TODO + cost of row/col index */,
|
|
||||||
|
|
||||||
FlagsLinearAccessBit = (traits<XprType>::RowsAtCompileTime == 1 || traits<XprType>::ColsAtCompileTime == 1) ? LinearAccessBit : 0,
|
|
||||||
|
|
||||||
FlagsRowMajorBit = traits<XprType>::FlagsRowMajorBit,
|
|
||||||
|
|
||||||
Flags = (evaluator<ArgType>::Flags & (HereditaryBits & ~RowMajorBit /*| LinearAccessBit | DirectAccessBit*/)) | FlagsLinearAccessBit | FlagsRowMajorBit,
|
|
||||||
|
|
||||||
Alignment = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& xpr) : m_argImpl(xpr.nestedExpression()), m_xpr(xpr)
|
|
||||||
{
|
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef typename XprType::Scalar Scalar;
|
|
||||||
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
CoeffReturnType coeff(Index row, Index col) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_xpr.rowIndices()[row] >= 0 && m_xpr.rowIndices()[row] < m_xpr.nestedExpression().rows()
|
|
||||||
&& m_xpr.colIndices()[col] >= 0 && m_xpr.colIndices()[col] < m_xpr.nestedExpression().cols());
|
|
||||||
return m_argImpl.coeff(m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
Scalar& coeffRef(Index row, Index col)
|
|
||||||
{
|
|
||||||
eigen_assert(m_xpr.rowIndices()[row] >= 0 && m_xpr.rowIndices()[row] < m_xpr.nestedExpression().rows()
|
|
||||||
&& m_xpr.colIndices()[col] >= 0 && m_xpr.colIndices()[col] < m_xpr.nestedExpression().cols());
|
|
||||||
return m_argImpl.coeffRef(m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
Scalar& coeffRef(Index index)
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT_LVALUE(XprType)
|
|
||||||
Index row = XprType::RowsAtCompileTime == 1 ? 0 : index;
|
|
||||||
Index col = XprType::RowsAtCompileTime == 1 ? index : 0;
|
|
||||||
eigen_assert(m_xpr.rowIndices()[row] >= 0 && m_xpr.rowIndices()[row] < m_xpr.nestedExpression().rows()
|
|
||||||
&& m_xpr.colIndices()[col] >= 0 && m_xpr.colIndices()[col] < m_xpr.nestedExpression().cols());
|
|
||||||
return m_argImpl.coeffRef( m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
const Scalar& coeffRef(Index index) const
|
|
||||||
{
|
|
||||||
Index row = XprType::RowsAtCompileTime == 1 ? 0 : index;
|
|
||||||
Index col = XprType::RowsAtCompileTime == 1 ? index : 0;
|
|
||||||
eigen_assert(m_xpr.rowIndices()[row] >= 0 && m_xpr.rowIndices()[row] < m_xpr.nestedExpression().rows()
|
|
||||||
&& m_xpr.colIndices()[col] >= 0 && m_xpr.colIndices()[col] < m_xpr.nestedExpression().cols());
|
|
||||||
return m_argImpl.coeffRef( m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
const CoeffReturnType coeff(Index index) const
|
|
||||||
{
|
|
||||||
Index row = XprType::RowsAtCompileTime == 1 ? 0 : index;
|
|
||||||
Index col = XprType::RowsAtCompileTime == 1 ? index : 0;
|
|
||||||
eigen_assert(m_xpr.rowIndices()[row] >= 0 && m_xpr.rowIndices()[row] < m_xpr.nestedExpression().rows()
|
|
||||||
&& m_xpr.colIndices()[col] >= 0 && m_xpr.colIndices()[col] < m_xpr.nestedExpression().cols());
|
|
||||||
return m_argImpl.coeff( m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
evaluator<ArgType> m_argImpl;
|
|
||||||
const XprType& m_xpr;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_INDEXED_VIEW_H
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
// for linear algebra.
|
// for linear algebra.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2014-2019 Gael Guennebaud <gael.guennebaud@inria.fr>
|
// Copyright (C) 2014 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// 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
|
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||||
@@ -44,6 +44,7 @@ class Inverse : public InverseImpl<XprType,typename internal::traits<XprType>::S
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename XprType::StorageIndex StorageIndex;
|
typedef typename XprType::StorageIndex StorageIndex;
|
||||||
|
typedef typename XprType::PlainObject PlainObject;
|
||||||
typedef typename XprType::Scalar Scalar;
|
typedef typename XprType::Scalar Scalar;
|
||||||
typedef typename internal::ref_selector<XprType>::type XprTypeNested;
|
typedef typename internal::ref_selector<XprType>::type XprTypeNested;
|
||||||
typedef typename internal::remove_all<XprTypeNested>::type XprTypeNestedCleaned;
|
typedef typename internal::remove_all<XprTypeNested>::type XprTypeNestedCleaned;
|
||||||
@@ -54,8 +55,8 @@ public:
|
|||||||
: m_xpr(xpr)
|
: m_xpr(xpr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_xpr.cols(); }
|
EIGEN_DEVICE_FUNC Index rows() const { return m_xpr.rows(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_xpr.rows(); }
|
EIGEN_DEVICE_FUNC Index cols() const { return m_xpr.cols(); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC const XprTypeNestedCleaned& nestedExpression() const { return m_xpr; }
|
EIGEN_DEVICE_FUNC const XprTypeNestedCleaned& nestedExpression() const { return m_xpr; }
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ private:
|
|||||||
* \brief A matrix or vector expression mapping an existing array of data.
|
* \brief A matrix or vector expression mapping an existing array of data.
|
||||||
*
|
*
|
||||||
* \tparam PlainObjectType the equivalent matrix type of the mapped data
|
* \tparam PlainObjectType the equivalent matrix type of the mapped data
|
||||||
* \tparam MapOptions specifies the pointer alignment in bytes. It can be: \c #Aligned128, \c #Aligned64, \c #Aligned32, \c #Aligned16, \c #Aligned8 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.
|
* The default is \c #Unaligned.
|
||||||
* \tparam StrideType optionally specifies strides. By default, Map assumes the memory layout
|
* \tparam StrideType optionally specifies strides. By default, Map assumes the memory layout
|
||||||
* of an ordinary, contiguous array. This can be overridden by specifying strides.
|
* of an ordinary, contiguous array. This can be overridden by specifying strides.
|
||||||
@@ -104,19 +104,19 @@ template<typename PlainObjectType, int MapOptions, typename StrideType> class Ma
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline PointerType cast_to_pointer_type(PointerArgType ptr) { return ptr; }
|
inline PointerType cast_to_pointer_type(PointerArgType ptr) { return ptr; }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index innerStride() const
|
inline Index innerStride() const
|
||||||
{
|
{
|
||||||
return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
|
return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index outerStride() const
|
inline Index outerStride() const
|
||||||
{
|
{
|
||||||
return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
|
return int(StrideType::OuterStrideAtCompileTime) != 0 ? m_stride.outer()
|
||||||
: internal::traits<Map>::OuterStrideAtCompileTime != Dynamic ? Index(internal::traits<Map>::OuterStrideAtCompileTime)
|
: int(internal::traits<Map>::OuterStrideAtCompileTime) != Dynamic ? Index(internal::traits<Map>::OuterStrideAtCompileTime)
|
||||||
: IsVectorAtCompileTime ? (this->size() * innerStride())
|
: IsVectorAtCompileTime ? (this->size() * innerStride())
|
||||||
: int(Flags)&RowMajorBit ? (this->cols() * innerStride())
|
: (int(Flags)&RowMajorBit) ? (this->cols() * innerStride())
|
||||||
: (this->rows() * innerStride());
|
: (this->rows() * innerStride());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -87,11 +87,9 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
|
|||||||
typedef typename Base::CoeffReturnType CoeffReturnType;
|
typedef typename Base::CoeffReturnType CoeffReturnType;
|
||||||
|
|
||||||
/** \copydoc DenseBase::rows() */
|
/** \copydoc DenseBase::rows() */
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC inline Index rows() const { return m_rows.value(); }
|
||||||
inline Index rows() const EIGEN_NOEXCEPT { return m_rows.value(); }
|
|
||||||
/** \copydoc DenseBase::cols() */
|
/** \copydoc DenseBase::cols() */
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC inline Index cols() const { return m_cols.value(); }
|
||||||
inline Index cols() const EIGEN_NOEXCEPT { return m_cols.value(); }
|
|
||||||
|
|
||||||
/** Returns a pointer to the first coefficient of the matrix or vector.
|
/** Returns a pointer to the first coefficient of the matrix or vector.
|
||||||
*
|
*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -17,28 +17,24 @@ namespace internal {
|
|||||||
|
|
||||||
/** \internal \returns the hyperbolic tan of \a a (coeff-wise)
|
/** \internal \returns the hyperbolic tan of \a a (coeff-wise)
|
||||||
Doesn't do anything fancy, just a 13/6-degree rational interpolant which
|
Doesn't do anything fancy, just a 13/6-degree rational interpolant which
|
||||||
is accurate up to a couple of ulps in the (approximate) range [-8, 8],
|
is accurate up to a couple of ulp in the range [-9, 9], outside of which
|
||||||
outside of which tanh(x) = +/-1 in single precision. The input is clamped
|
the tanh(x) = +/-1.
|
||||||
to the range [-c, c]. The value c is chosen as the smallest value where
|
|
||||||
the approximation evaluates to exactly 1. In the reange [-0.0004, 0.0004]
|
|
||||||
the approxmation tanh(x) ~= x is used for better accuracy as x tends to zero.
|
|
||||||
|
|
||||||
This implementation works on both scalars and packets.
|
This implementation works on both scalars and packets.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T generic_fast_tanh_float(const T& a_x)
|
T generic_fast_tanh_float(const T& a_x)
|
||||||
{
|
{
|
||||||
// Clamp the inputs to the range [-c, c]
|
// Clamp the inputs to the range [-9, 9] since anything outside
|
||||||
#ifdef EIGEN_VECTORIZE_FMA
|
// this range is +/-1.0f in single-precision.
|
||||||
const T plus_clamp = pset1<T>(7.99881172180175781f);
|
const T plus_9 = pset1<T>(9.f);
|
||||||
const T minus_clamp = pset1<T>(-7.99881172180175781f);
|
const T minus_9 = pset1<T>(-9.f);
|
||||||
#else
|
// NOTE GCC prior to 6.3 might improperly optimize this max/min
|
||||||
const T plus_clamp = pset1<T>(7.90531110763549805f);
|
// step such that if a_x is nan, x will be either 9 or -9,
|
||||||
const T minus_clamp = pset1<T>(-7.90531110763549805f);
|
// and tanh will return 1 or -1 instead of nan.
|
||||||
#endif
|
// This is supposed to be fixed in gcc6.3,
|
||||||
const T tiny = pset1<T>(0.0004f);
|
// see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72867
|
||||||
const T x = pmax(pmin(a_x, plus_clamp), minus_clamp);
|
const T x = pmax(minus_9,pmin(plus_9,a_x));
|
||||||
const T tiny_mask = pcmp_lt(pabs(a_x), tiny);
|
|
||||||
// The monomial coefficients of the numerator polynomial (odd).
|
// The monomial coefficients of the numerator polynomial (odd).
|
||||||
const T alpha_1 = pset1<T>(4.89352455891786e-03f);
|
const T alpha_1 = pset1<T>(4.89352455891786e-03f);
|
||||||
const T alpha_3 = pset1<T>(6.37261928875436e-04f);
|
const T alpha_3 = pset1<T>(6.37261928875436e-04f);
|
||||||
@@ -66,26 +62,20 @@ T generic_fast_tanh_float(const T& a_x)
|
|||||||
p = pmadd(x2, p, alpha_1);
|
p = pmadd(x2, p, alpha_1);
|
||||||
p = pmul(x, p);
|
p = pmul(x, p);
|
||||||
|
|
||||||
// Evaluate the denominator polynomial q.
|
// Evaluate the denominator polynomial p.
|
||||||
T q = pmadd(x2, beta_6, beta_4);
|
T q = pmadd(x2, beta_6, beta_4);
|
||||||
q = pmadd(x2, q, beta_2);
|
q = pmadd(x2, q, beta_2);
|
||||||
q = pmadd(x2, q, beta_0);
|
q = pmadd(x2, q, beta_0);
|
||||||
|
|
||||||
// Divide the numerator by the denominator.
|
// Divide the numerator by the denominator.
|
||||||
return pselect(tiny_mask, x, pdiv(p, q));
|
return pdiv(p, q);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RealScalar>
|
template<typename RealScalar>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_STRONG_INLINE
|
||||||
RealScalar positive_real_hypot(const RealScalar& x, const RealScalar& y)
|
RealScalar positive_real_hypot(const RealScalar& x, const RealScalar& y)
|
||||||
{
|
{
|
||||||
// IEEE IEC 6059 special cases.
|
EIGEN_USING_STD_MATH(sqrt);
|
||||||
if ((numext::isinf)(x) || (numext::isinf)(y))
|
|
||||||
return NumTraits<RealScalar>::infinity();
|
|
||||||
if ((numext::isnan)(x) || (numext::isnan)(y))
|
|
||||||
return NumTraits<RealScalar>::quiet_NaN();
|
|
||||||
|
|
||||||
EIGEN_USING_STD(sqrt);
|
|
||||||
RealScalar p, qp;
|
RealScalar p, qp;
|
||||||
p = numext::maxi(x,y);
|
p = numext::maxi(x,y);
|
||||||
if(p==RealScalar(0)) return RealScalar(0);
|
if(p==RealScalar(0)) return RealScalar(0);
|
||||||
@@ -97,102 +87,13 @@ template<typename Scalar>
|
|||||||
struct hypot_impl
|
struct hypot_impl
|
||||||
{
|
{
|
||||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||||
static EIGEN_DEVICE_FUNC
|
static inline RealScalar run(const Scalar& x, const Scalar& y)
|
||||||
inline RealScalar run(const Scalar& x, const Scalar& y)
|
|
||||||
{
|
{
|
||||||
EIGEN_USING_STD(abs);
|
EIGEN_USING_STD_MATH(abs);
|
||||||
return positive_real_hypot<RealScalar>(abs(x), abs(y));
|
return positive_real_hypot<RealScalar>(abs(x), abs(y));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generic complex sqrt implementation that correctly handles corner cases
|
|
||||||
// according to https://en.cppreference.com/w/cpp/numeric/complex/sqrt
|
|
||||||
template<typename T>
|
|
||||||
EIGEN_DEVICE_FUNC std::complex<T> complex_sqrt(const std::complex<T>& z) {
|
|
||||||
// Computes the principal sqrt of the input.
|
|
||||||
//
|
|
||||||
// For a complex square root of the number x + i*y. We want to find real
|
|
||||||
// numbers u and v such that
|
|
||||||
// (u + i*v)^2 = x + i*y <=>
|
|
||||||
// u^2 - v^2 + i*2*u*v = x + i*v.
|
|
||||||
// By equating the real and imaginary parts we get:
|
|
||||||
// u^2 - v^2 = x
|
|
||||||
// 2*u*v = y.
|
|
||||||
//
|
|
||||||
// For x >= 0, this has the numerically stable solution
|
|
||||||
// u = sqrt(0.5 * (x + sqrt(x^2 + y^2)))
|
|
||||||
// v = y / (2 * u)
|
|
||||||
// and for x < 0,
|
|
||||||
// v = sign(y) * sqrt(0.5 * (-x + sqrt(x^2 + y^2)))
|
|
||||||
// u = y / (2 * v)
|
|
||||||
//
|
|
||||||
// Letting w = sqrt(0.5 * (|x| + |z|)),
|
|
||||||
// if x == 0: u = w, v = sign(y) * w
|
|
||||||
// if x > 0: u = w, v = y / (2 * w)
|
|
||||||
// if x < 0: u = |y| / (2 * w), v = sign(y) * w
|
|
||||||
|
|
||||||
const T x = numext::real(z);
|
|
||||||
const T y = numext::imag(z);
|
|
||||||
const T zero = T(0);
|
|
||||||
const T w = numext::sqrt(T(0.5) * (numext::abs(x) + numext::hypot(x, y)));
|
|
||||||
|
|
||||||
return
|
|
||||||
(numext::isinf)(y) ? std::complex<T>(NumTraits<T>::infinity(), y)
|
|
||||||
: x == zero ? std::complex<T>(w, y < zero ? -w : w)
|
|
||||||
: x > zero ? std::complex<T>(w, y / (2 * w))
|
|
||||||
: std::complex<T>(numext::abs(y) / (2 * w), y < zero ? -w : w );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generic complex rsqrt implementation.
|
|
||||||
template<typename T>
|
|
||||||
EIGEN_DEVICE_FUNC std::complex<T> complex_rsqrt(const std::complex<T>& z) {
|
|
||||||
// Computes the principal reciprocal sqrt of the input.
|
|
||||||
//
|
|
||||||
// For a complex reciprocal square root of the number z = x + i*y. We want to
|
|
||||||
// find real numbers u and v such that
|
|
||||||
// (u + i*v)^2 = 1 / (x + i*y) <=>
|
|
||||||
// u^2 - v^2 + i*2*u*v = x/|z|^2 - i*v/|z|^2.
|
|
||||||
// By equating the real and imaginary parts we get:
|
|
||||||
// u^2 - v^2 = x/|z|^2
|
|
||||||
// 2*u*v = y/|z|^2.
|
|
||||||
//
|
|
||||||
// For x >= 0, this has the numerically stable solution
|
|
||||||
// u = sqrt(0.5 * (x + |z|)) / |z|
|
|
||||||
// v = -y / (2 * u * |z|)
|
|
||||||
// and for x < 0,
|
|
||||||
// v = -sign(y) * sqrt(0.5 * (-x + |z|)) / |z|
|
|
||||||
// u = -y / (2 * v * |z|)
|
|
||||||
//
|
|
||||||
// Letting w = sqrt(0.5 * (|x| + |z|)),
|
|
||||||
// if x == 0: u = w / |z|, v = -sign(y) * w / |z|
|
|
||||||
// if x > 0: u = w / |z|, v = -y / (2 * w * |z|)
|
|
||||||
// if x < 0: u = |y| / (2 * w * |z|), v = -sign(y) * w / |z|
|
|
||||||
|
|
||||||
const T x = numext::real(z);
|
|
||||||
const T y = numext::imag(z);
|
|
||||||
const T zero = T(0);
|
|
||||||
|
|
||||||
const T abs_z = numext::hypot(x, y);
|
|
||||||
const T w = numext::sqrt(T(0.5) * (numext::abs(x) + abs_z));
|
|
||||||
const T woz = w / abs_z;
|
|
||||||
// Corner cases consistent with 1/sqrt(z) on gcc/clang.
|
|
||||||
return
|
|
||||||
abs_z == zero ? std::complex<T>(NumTraits<T>::infinity(), NumTraits<T>::quiet_NaN())
|
|
||||||
: ((numext::isinf)(x) || (numext::isinf)(y)) ? std::complex<T>(zero, zero)
|
|
||||||
: x == zero ? std::complex<T>(woz, y < zero ? woz : -woz)
|
|
||||||
: x > zero ? std::complex<T>(woz, -y / (2 * w * abs_z))
|
|
||||||
: std::complex<T>(numext::abs(y) / (2 * w * abs_z), y < zero ? woz : -woz );
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
EIGEN_DEVICE_FUNC std::complex<T> complex_log(const std::complex<T>& z) {
|
|
||||||
// Computes complex log.
|
|
||||||
T a = numext::abs(z);
|
|
||||||
EIGEN_USING_STD(atan2);
|
|
||||||
T b = atan2(z.imag(), z.real());
|
|
||||||
return std::complex<T>(numext::log(a), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|||||||
@@ -225,6 +225,8 @@ class Matrix
|
|||||||
return Base::_set(other);
|
return Base::_set(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Here, doxygen failed to copy the brief information when using \copydoc */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Copies the generic expression \a other into *this.
|
* \brief Copies the generic expression \a other into *this.
|
||||||
* \copydetails DenseBase::operator=(const EigenBase<OtherDerived> &other)
|
* \copydetails DenseBase::operator=(const EigenBase<OtherDerived> &other)
|
||||||
@@ -253,103 +255,53 @@ class Matrix
|
|||||||
*
|
*
|
||||||
* \sa resize(Index,Index)
|
* \sa resize(Index,Index)
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
Matrix() : Base()
|
EIGEN_STRONG_INLINE Matrix() : Base()
|
||||||
{
|
{
|
||||||
Base::_check_template_params();
|
Base::_check_template_params();
|
||||||
EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
|
EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME is it still needed
|
// FIXME is it still needed
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
explicit Matrix(internal::constructor_without_unaligned_array_assert)
|
explicit Matrix(internal::constructor_without_unaligned_array_assert)
|
||||||
: Base(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 }
|
{ Base::_check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED }
|
||||||
|
|
||||||
#if EIGEN_HAS_RVALUE_REFERENCES
|
#if EIGEN_HAS_RVALUE_REFERENCES
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
Matrix(Matrix&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_constructible<Scalar>::value)
|
Matrix(Matrix&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_constructible<Scalar>::value)
|
||||||
: Base(std::move(other))
|
: Base(std::move(other))
|
||||||
{
|
{
|
||||||
Base::_check_template_params();
|
Base::_check_template_params();
|
||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
Matrix& operator=(Matrix&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_assignable<Scalar>::value)
|
Matrix& operator=(Matrix&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_assignable<Scalar>::value)
|
||||||
{
|
{
|
||||||
Base::operator=(std::move(other));
|
other.swap(*this);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if EIGEN_HAS_CXX11
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
/** \brief Construct a row of column vector with fixed size from an arbitrary number of coefficients. \cpp11
|
|
||||||
*
|
|
||||||
* \only_for_vectors
|
|
||||||
*
|
|
||||||
* This constructor is for 1D array or vectors with more than 4 coefficients.
|
|
||||||
* There exists C++98 analogue constructors for fixed-size array/vector having 1, 2, 3, or 4 coefficients.
|
|
||||||
*
|
|
||||||
* \warning To construct a column (resp. row) vector of fixed length, the number of values passed to this
|
|
||||||
* constructor must match the the fixed number of rows (resp. columns) of \c *this.
|
|
||||||
*
|
|
||||||
* Example: \include Matrix_variadic_ctor_cxx11.cpp
|
|
||||||
* Output: \verbinclude Matrix_variadic_ctor_cxx11.out
|
|
||||||
*
|
|
||||||
* \sa Matrix(const std::initializer_list<std::initializer_list<Scalar>>&)
|
|
||||||
*/
|
|
||||||
template <typename... ArgTypes>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
Matrix(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args)
|
|
||||||
: Base(a0, a1, a2, a3, args...) {}
|
|
||||||
|
|
||||||
/** \brief Constructs a Matrix and initializes it from the coefficients given as initializer-lists grouped by row. \cpp11
|
|
||||||
*
|
|
||||||
* \anchor matrix_constructor_initializer_list
|
|
||||||
*
|
|
||||||
* In the general case, the constructor takes a list of rows, each row being represented as a list of coefficients:
|
|
||||||
*
|
|
||||||
* Example: \include Matrix_initializer_list_23_cxx11.cpp
|
|
||||||
* Output: \verbinclude Matrix_initializer_list_23_cxx11.out
|
|
||||||
*
|
|
||||||
* Each of the inner initializer lists must contain the exact same number of elements, otherwise an assertion is triggered.
|
|
||||||
*
|
|
||||||
* In the case of a compile-time column vector, implicit transposition from a single row is allowed.
|
|
||||||
* Therefore <code>VectorXd{{1,2,3,4,5}}</code> is legal and the more verbose syntax
|
|
||||||
* <code>RowVectorXd{{1},{2},{3},{4},{5}}</code> can be avoided:
|
|
||||||
*
|
|
||||||
* Example: \include Matrix_initializer_list_vector_cxx11.cpp
|
|
||||||
* Output: \verbinclude Matrix_initializer_list_vector_cxx11.out
|
|
||||||
*
|
|
||||||
* In the case of fixed-sized matrices, the initializer list sizes must exactly match the matrix sizes,
|
|
||||||
* and implicit transposition is allowed for compile-time vectors only.
|
|
||||||
*
|
|
||||||
* \sa Matrix(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args)
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
explicit EIGEN_STRONG_INLINE Matrix(const std::initializer_list<std::initializer_list<Scalar>>& list) : Base(list) {}
|
|
||||||
#endif // end EIGEN_HAS_CXX11
|
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
|
|
||||||
// This constructor is for both 1x1 matrices and dynamic vectors
|
// This constructor is for both 1x1 matrices and dynamic vectors
|
||||||
template<typename T>
|
template<typename T>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
explicit Matrix(const T& x)
|
EIGEN_STRONG_INLINE explicit Matrix(const T& x)
|
||||||
{
|
{
|
||||||
Base::_check_template_params();
|
Base::_check_template_params();
|
||||||
Base::template _init1<T>(x);
|
Base::template _init1<T>(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T0, typename T1>
|
template<typename T0, typename T1>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
Matrix(const T0& x, const T1& y)
|
EIGEN_STRONG_INLINE Matrix(const T0& x, const T1& y)
|
||||||
{
|
{
|
||||||
Base::_check_template_params();
|
Base::_check_template_params();
|
||||||
Base::template _init2<T0,T1>(x, y);
|
Base::template _init2<T0,T1>(x, y);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
#else
|
|
||||||
/** \brief Constructs a fixed-sized matrix initialized with coefficients starting at \a data */
|
/** \brief Constructs a fixed-sized matrix initialized with coefficients starting at \a data */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
explicit Matrix(const Scalar *data);
|
explicit Matrix(const Scalar *data);
|
||||||
@@ -367,8 +319,7 @@ class Matrix
|
|||||||
* \c EIGEN_INITIALIZE_MATRICES_BY_{ZERO,\c NAN} macros (see \ref TopicPreprocessorDirectives).
|
* \c EIGEN_INITIALIZE_MATRICES_BY_{ZERO,\c NAN} macros (see \ref TopicPreprocessorDirectives).
|
||||||
*/
|
*/
|
||||||
EIGEN_STRONG_INLINE explicit Matrix(Index dim);
|
EIGEN_STRONG_INLINE explicit Matrix(Index dim);
|
||||||
/** \brief Constructs an initialized 1x1 matrix with the given coefficient
|
/** \brief Constructs an initialized 1x1 matrix with the given coefficient */
|
||||||
* \sa Matrix(const Scalar&, const Scalar&, const Scalar&, const Scalar&, const ArgTypes&...) */
|
|
||||||
Matrix(const Scalar& x);
|
Matrix(const Scalar& x);
|
||||||
/** \brief Constructs an uninitialized matrix with \a rows rows and \a cols columns.
|
/** \brief Constructs an uninitialized matrix with \a rows rows and \a cols columns.
|
||||||
*
|
*
|
||||||
@@ -385,14 +336,11 @@ class Matrix
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
Matrix(Index rows, Index cols);
|
Matrix(Index rows, Index cols);
|
||||||
|
|
||||||
/** \brief Constructs an initialized 2D vector with given coefficients
|
/** \brief Constructs an initialized 2D vector with given coefficients */
|
||||||
* \sa Matrix(const Scalar&, const Scalar&, const Scalar&, const Scalar&, const ArgTypes&...) */
|
|
||||||
Matrix(const Scalar& x, const Scalar& y);
|
Matrix(const Scalar& x, const Scalar& y);
|
||||||
#endif // end EIGEN_PARSED_BY_DOXYGEN
|
#endif
|
||||||
|
|
||||||
/** \brief Constructs an initialized 3D vector with given coefficients
|
/** \brief Constructs an initialized 3D vector with given coefficients */
|
||||||
* \sa Matrix(const Scalar&, const Scalar&, const Scalar&, const Scalar&, const ArgTypes&...)
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z)
|
EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z)
|
||||||
{
|
{
|
||||||
@@ -402,9 +350,7 @@ class Matrix
|
|||||||
m_storage.data()[1] = y;
|
m_storage.data()[1] = y;
|
||||||
m_storage.data()[2] = z;
|
m_storage.data()[2] = z;
|
||||||
}
|
}
|
||||||
/** \brief Constructs an initialized 4D vector with given coefficients
|
/** \brief Constructs an initialized 4D vector with given coefficients */
|
||||||
* \sa Matrix(const Scalar&, const Scalar&, const Scalar&, const Scalar&, const ArgTypes&...)
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w)
|
EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w)
|
||||||
{
|
{
|
||||||
@@ -431,10 +377,8 @@ class Matrix
|
|||||||
: Base(other.derived())
|
: Base(other.derived())
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC inline Index innerStride() const { return 1; }
|
||||||
inline Index innerStride() const EIGEN_NOEXCEPT { return 1; }
|
EIGEN_DEVICE_FUNC inline Index outerStride() const { return this->innerSize(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
|
||||||
inline Index outerStride() const EIGEN_NOEXCEPT { return this->innerSize(); }
|
|
||||||
|
|
||||||
/////////// Geometry module ///////////
|
/////////// Geometry module ///////////
|
||||||
|
|
||||||
@@ -461,7 +405,7 @@ class Matrix
|
|||||||
*
|
*
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
*
|
*
|
||||||
* %Eigen defines several typedef shortcuts for most common matrix and vector types.
|
* Eigen defines several typedef shortcuts for most common matrix and vector types.
|
||||||
*
|
*
|
||||||
* The general patterns are the following:
|
* The general patterns are the following:
|
||||||
*
|
*
|
||||||
@@ -474,35 +418,21 @@ class Matrix
|
|||||||
* There are also \c VectorSizeType and \c RowVectorSizeType which are self-explanatory. For example, \c Vector4cf is
|
* There are also \c VectorSizeType and \c RowVectorSizeType which are self-explanatory. For example, \c Vector4cf is
|
||||||
* a fixed-size vector of 4 complex floats.
|
* a fixed-size vector of 4 complex floats.
|
||||||
*
|
*
|
||||||
* With \cpp11, template alias are also defined for common sizes.
|
|
||||||
* They follow the same pattern as above except that the scalar type suffix is replaced by a
|
|
||||||
* template parameter, i.e.:
|
|
||||||
* - `MatrixSize<Type>` where `Size` can be \c 2,\c 3,\c 4 for fixed size square matrices or \c X for dynamic size.
|
|
||||||
* - `MatrixXSize<Type>` and `MatrixSizeX<Type>` where `Size` can be \c 2,\c 3,\c 4 for hybrid dynamic/fixed matrices.
|
|
||||||
* - `VectorSize<Type>` and `RowVectorSize<Type>` for column and row vectors.
|
|
||||||
*
|
|
||||||
* With \cpp11, you can also use fully generic column and row vector types: `Vector<Type,Size>` and `RowVector<Type,Size>`.
|
|
||||||
*
|
|
||||||
* \sa class Matrix
|
* \sa class Matrix
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix) \
|
#define EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix) \
|
||||||
/** \ingroup matrixtypedefs */ \
|
/** \ingroup matrixtypedefs */ \
|
||||||
/** \brief \noop */ \
|
|
||||||
typedef Matrix<Type, Size, Size> Matrix##SizeSuffix##TypeSuffix; \
|
typedef Matrix<Type, Size, Size> Matrix##SizeSuffix##TypeSuffix; \
|
||||||
/** \ingroup matrixtypedefs */ \
|
/** \ingroup matrixtypedefs */ \
|
||||||
/** \brief \noop */ \
|
|
||||||
typedef Matrix<Type, Size, 1> Vector##SizeSuffix##TypeSuffix; \
|
typedef Matrix<Type, Size, 1> Vector##SizeSuffix##TypeSuffix; \
|
||||||
/** \ingroup matrixtypedefs */ \
|
/** \ingroup matrixtypedefs */ \
|
||||||
/** \brief \noop */ \
|
|
||||||
typedef Matrix<Type, 1, Size> RowVector##SizeSuffix##TypeSuffix;
|
typedef Matrix<Type, 1, Size> RowVector##SizeSuffix##TypeSuffix;
|
||||||
|
|
||||||
#define EIGEN_MAKE_FIXED_TYPEDEFS(Type, TypeSuffix, Size) \
|
#define EIGEN_MAKE_FIXED_TYPEDEFS(Type, TypeSuffix, Size) \
|
||||||
/** \ingroup matrixtypedefs */ \
|
/** \ingroup matrixtypedefs */ \
|
||||||
/** \brief \noop */ \
|
|
||||||
typedef Matrix<Type, Size, Dynamic> Matrix##Size##X##TypeSuffix; \
|
typedef Matrix<Type, Size, Dynamic> Matrix##Size##X##TypeSuffix; \
|
||||||
/** \ingroup matrixtypedefs */ \
|
/** \ingroup matrixtypedefs */ \
|
||||||
/** \brief \noop */ \
|
|
||||||
typedef Matrix<Type, Dynamic, Size> Matrix##X##Size##TypeSuffix;
|
typedef Matrix<Type, Dynamic, Size> Matrix##X##Size##TypeSuffix;
|
||||||
|
|
||||||
#define EIGEN_MAKE_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \
|
#define EIGEN_MAKE_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \
|
||||||
@@ -524,55 +454,6 @@ EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex<double>, cd)
|
|||||||
#undef EIGEN_MAKE_TYPEDEFS
|
#undef EIGEN_MAKE_TYPEDEFS
|
||||||
#undef EIGEN_MAKE_FIXED_TYPEDEFS
|
#undef EIGEN_MAKE_FIXED_TYPEDEFS
|
||||||
|
|
||||||
#if EIGEN_HAS_CXX11
|
|
||||||
|
|
||||||
#define EIGEN_MAKE_TYPEDEFS(Size, SizeSuffix) \
|
|
||||||
/** \ingroup matrixtypedefs */ \
|
|
||||||
/** \brief \cpp11 */ \
|
|
||||||
template <typename Type> \
|
|
||||||
using Matrix##SizeSuffix = Matrix<Type, Size, Size>; \
|
|
||||||
/** \ingroup matrixtypedefs */ \
|
|
||||||
/** \brief \cpp11 */ \
|
|
||||||
template <typename Type> \
|
|
||||||
using Vector##SizeSuffix = Matrix<Type, Size, 1>; \
|
|
||||||
/** \ingroup matrixtypedefs */ \
|
|
||||||
/** \brief \cpp11 */ \
|
|
||||||
template <typename Type> \
|
|
||||||
using RowVector##SizeSuffix = Matrix<Type, 1, Size>;
|
|
||||||
|
|
||||||
#define EIGEN_MAKE_FIXED_TYPEDEFS(Size) \
|
|
||||||
/** \ingroup matrixtypedefs */ \
|
|
||||||
/** \brief \cpp11 */ \
|
|
||||||
template <typename Type> \
|
|
||||||
using Matrix##Size##X = Matrix<Type, Size, Dynamic>; \
|
|
||||||
/** \ingroup matrixtypedefs */ \
|
|
||||||
/** \brief \cpp11 */ \
|
|
||||||
template <typename Type> \
|
|
||||||
using Matrix##X##Size = Matrix<Type, Dynamic, Size>;
|
|
||||||
|
|
||||||
EIGEN_MAKE_TYPEDEFS(2, 2)
|
|
||||||
EIGEN_MAKE_TYPEDEFS(3, 3)
|
|
||||||
EIGEN_MAKE_TYPEDEFS(4, 4)
|
|
||||||
EIGEN_MAKE_TYPEDEFS(Dynamic, X)
|
|
||||||
EIGEN_MAKE_FIXED_TYPEDEFS(2)
|
|
||||||
EIGEN_MAKE_FIXED_TYPEDEFS(3)
|
|
||||||
EIGEN_MAKE_FIXED_TYPEDEFS(4)
|
|
||||||
|
|
||||||
/** \ingroup matrixtypedefs
|
|
||||||
* \brief \cpp11 */
|
|
||||||
template <typename Type, int Size>
|
|
||||||
using Vector = Matrix<Type, Size, 1>;
|
|
||||||
|
|
||||||
/** \ingroup matrixtypedefs
|
|
||||||
* \brief \cpp11 */
|
|
||||||
template <typename Type, int Size>
|
|
||||||
using RowVector = Matrix<Type, 1, Size>;
|
|
||||||
|
|
||||||
#undef EIGEN_MAKE_TYPEDEFS
|
|
||||||
#undef EIGEN_MAKE_FIXED_TYPEDEFS
|
|
||||||
|
|
||||||
#endif // EIGEN_HAS_CXX11
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_MATRIX_H
|
#endif // EIGEN_MATRIX_H
|
||||||
|
|||||||
@@ -76,7 +76,6 @@ template<typename Derived> class MatrixBase
|
|||||||
using Base::coeffRef;
|
using Base::coeffRef;
|
||||||
using Base::lazyAssign;
|
using Base::lazyAssign;
|
||||||
using Base::eval;
|
using Base::eval;
|
||||||
using Base::operator-;
|
|
||||||
using Base::operator+=;
|
using Base::operator+=;
|
||||||
using Base::operator-=;
|
using Base::operator-=;
|
||||||
using Base::operator*=;
|
using Base::operator*=;
|
||||||
@@ -123,6 +122,7 @@ template<typename Derived> class MatrixBase
|
|||||||
|
|
||||||
#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::MatrixBase
|
#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::MatrixBase
|
||||||
#define EIGEN_DOC_UNARY_ADDONS(X,Y)
|
#define EIGEN_DOC_UNARY_ADDONS(X,Y)
|
||||||
|
# include "../plugins/CommonCwiseUnaryOps.h"
|
||||||
# include "../plugins/CommonCwiseBinaryOps.h"
|
# include "../plugins/CommonCwiseBinaryOps.h"
|
||||||
# include "../plugins/MatrixCwiseUnaryOps.h"
|
# include "../plugins/MatrixCwiseUnaryOps.h"
|
||||||
# include "../plugins/MatrixCwiseBinaryOps.h"
|
# include "../plugins/MatrixCwiseBinaryOps.h"
|
||||||
@@ -206,22 +206,28 @@ template<typename Derived> class MatrixBase
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
DiagonalReturnType diagonal();
|
DiagonalReturnType diagonal();
|
||||||
|
|
||||||
typedef Diagonal<const Derived> ConstDiagonalReturnType;
|
typedef typename internal::add_const<Diagonal<const Derived> >::type ConstDiagonalReturnType;
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const ConstDiagonalReturnType diagonal() const;
|
ConstDiagonalReturnType diagonal() const;
|
||||||
|
|
||||||
|
template<int Index> struct DiagonalIndexReturnType { typedef Diagonal<Derived,Index> Type; };
|
||||||
|
template<int Index> struct ConstDiagonalIndexReturnType { typedef const Diagonal<const Derived,Index> Type; };
|
||||||
|
|
||||||
template<int Index>
|
template<int Index>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
Diagonal<Derived, Index> diagonal();
|
typename DiagonalIndexReturnType<Index>::Type diagonal();
|
||||||
|
|
||||||
template<int Index>
|
template<int Index>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const Diagonal<const Derived, Index> diagonal() const;
|
typename ConstDiagonalIndexReturnType<Index>::Type diagonal() const;
|
||||||
|
|
||||||
|
typedef Diagonal<Derived,DynamicIndex> DiagonalDynamicIndexReturnType;
|
||||||
|
typedef typename internal::add_const<Diagonal<const Derived,DynamicIndex> >::type ConstDiagonalDynamicIndexReturnType;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
Diagonal<Derived, DynamicIndex> diagonal(Index index);
|
DiagonalDynamicIndexReturnType diagonal(Index index);
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const Diagonal<const Derived, DynamicIndex> diagonal(Index index) const;
|
ConstDiagonalDynamicIndexReturnType diagonal(Index index) const;
|
||||||
|
|
||||||
template<unsigned int Mode> struct TriangularViewReturnType { typedef TriangularView<Derived, Mode> Type; };
|
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> struct ConstTriangularViewReturnType { typedef const TriangularView<const Derived, Mode> Type; };
|
||||||
@@ -262,8 +268,6 @@ template<typename Derived> class MatrixBase
|
|||||||
Derived& setIdentity();
|
Derived& setIdentity();
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
Derived& setIdentity(Index rows, Index cols);
|
Derived& setIdentity(Index rows, Index cols);
|
||||||
EIGEN_DEVICE_FUNC Derived& setUnit(Index i);
|
|
||||||
EIGEN_DEVICE_FUNC Derived& setUnit(Index newSize, Index i);
|
|
||||||
|
|
||||||
bool isIdentity(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
bool isIdentity(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||||
bool isDiagonal(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
bool isDiagonal(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||||
@@ -292,7 +296,7 @@ template<typename Derived> class MatrixBase
|
|||||||
EIGEN_DEVICE_FUNC inline bool operator!=(const MatrixBase<OtherDerived>& other) const
|
EIGEN_DEVICE_FUNC inline bool operator!=(const MatrixBase<OtherDerived>& other) const
|
||||||
{ return cwiseNotEqual(other).any(); }
|
{ return cwiseNotEqual(other).any(); }
|
||||||
|
|
||||||
NoAlias<Derived,Eigen::MatrixBase > EIGEN_DEVICE_FUNC noalias();
|
NoAlias<Derived,Eigen::MatrixBase > noalias();
|
||||||
|
|
||||||
// TODO forceAlignedAccess is temporarily disabled
|
// TODO forceAlignedAccess is temporarily disabled
|
||||||
// Need to find a nicer workaround.
|
// Need to find a nicer workaround.
|
||||||
@@ -322,7 +326,6 @@ template<typename Derived> class MatrixBase
|
|||||||
|
|
||||||
inline const PartialPivLU<PlainObject> lu() const;
|
inline const PartialPivLU<PlainObject> lu() const;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline const Inverse<Derived> inverse() const;
|
inline const Inverse<Derived> inverse() const;
|
||||||
|
|
||||||
template<typename ResultType>
|
template<typename ResultType>
|
||||||
@@ -332,15 +335,12 @@ template<typename Derived> class MatrixBase
|
|||||||
bool& invertible,
|
bool& invertible,
|
||||||
const RealScalar& absDeterminantThreshold = NumTraits<Scalar>::dummy_precision()
|
const RealScalar& absDeterminantThreshold = NumTraits<Scalar>::dummy_precision()
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
template<typename ResultType>
|
template<typename ResultType>
|
||||||
inline void computeInverseWithCheck(
|
inline void computeInverseWithCheck(
|
||||||
ResultType& inverse,
|
ResultType& inverse,
|
||||||
bool& invertible,
|
bool& invertible,
|
||||||
const RealScalar& absDeterminantThreshold = NumTraits<Scalar>::dummy_precision()
|
const RealScalar& absDeterminantThreshold = NumTraits<Scalar>::dummy_precision()
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
Scalar determinant() const;
|
Scalar determinant() const;
|
||||||
|
|
||||||
/////////// Cholesky module ///////////
|
/////////// Cholesky module ///////////
|
||||||
@@ -412,19 +412,15 @@ template<typename Derived> class MatrixBase
|
|||||||
|
|
||||||
////////// Householder module ///////////
|
////////// Householder module ///////////
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
void makeHouseholderInPlace(Scalar& tau, RealScalar& beta);
|
void makeHouseholderInPlace(Scalar& tau, RealScalar& beta);
|
||||||
template<typename EssentialPart>
|
template<typename EssentialPart>
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
void makeHouseholder(EssentialPart& essential,
|
void makeHouseholder(EssentialPart& essential,
|
||||||
Scalar& tau, RealScalar& beta) const;
|
Scalar& tau, RealScalar& beta) const;
|
||||||
template<typename EssentialPart>
|
template<typename EssentialPart>
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
void applyHouseholderOnTheLeft(const EssentialPart& essential,
|
void applyHouseholderOnTheLeft(const EssentialPart& essential,
|
||||||
const Scalar& tau,
|
const Scalar& tau,
|
||||||
Scalar* workspace);
|
Scalar* workspace);
|
||||||
template<typename EssentialPart>
|
template<typename EssentialPart>
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
void applyHouseholderOnTheRight(const EssentialPart& essential,
|
void applyHouseholderOnTheRight(const EssentialPart& essential,
|
||||||
const Scalar& tau,
|
const Scalar& tau,
|
||||||
Scalar* workspace);
|
Scalar* workspace);
|
||||||
@@ -432,10 +428,8 @@ template<typename Derived> class MatrixBase
|
|||||||
///////// Jacobi module /////////
|
///////// Jacobi module /////////
|
||||||
|
|
||||||
template<typename OtherScalar>
|
template<typename OtherScalar>
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
void applyOnTheLeft(Index p, Index q, const JacobiRotation<OtherScalar>& j);
|
void applyOnTheLeft(Index p, Index q, const JacobiRotation<OtherScalar>& j);
|
||||||
template<typename OtherScalar>
|
template<typename OtherScalar>
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
void applyOnTheRight(Index p, Index q, const JacobiRotation<OtherScalar>& j);
|
void applyOnTheRight(Index p, Index q, const JacobiRotation<OtherScalar>& j);
|
||||||
|
|
||||||
///////// SparseCore module /////////
|
///////// SparseCore module /////////
|
||||||
@@ -462,11 +456,6 @@ template<typename Derived> class MatrixBase
|
|||||||
const MatrixFunctionReturnValue<Derived> matrixFunction(StemFunction f) const;
|
const MatrixFunctionReturnValue<Derived> matrixFunction(StemFunction f) const;
|
||||||
EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, cosh, hyperbolic cosine)
|
EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, cosh, hyperbolic cosine)
|
||||||
EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, sinh, hyperbolic sine)
|
EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, sinh, hyperbolic sine)
|
||||||
#if EIGEN_HAS_CXX11_MATH
|
|
||||||
EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, atanh, inverse hyperbolic cosine)
|
|
||||||
EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, acosh, inverse hyperbolic cosine)
|
|
||||||
EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, asinh, inverse hyperbolic sine)
|
|
||||||
#endif
|
|
||||||
EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, cos, cosine)
|
EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, cos, cosine)
|
||||||
EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, sin, sine)
|
EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, sin, sine)
|
||||||
EIGEN_MATRIX_FUNCTION(MatrixSquareRootReturnValue, sqrt, square root)
|
EIGEN_MATRIX_FUNCTION(MatrixSquareRootReturnValue, sqrt, square root)
|
||||||
|
|||||||
@@ -16,11 +16,7 @@ namespace Eigen {
|
|||||||
namespace internal {
|
namespace internal {
|
||||||
template<typename ExpressionType>
|
template<typename ExpressionType>
|
||||||
struct traits<NestByValue<ExpressionType> > : public traits<ExpressionType>
|
struct traits<NestByValue<ExpressionType> > : public traits<ExpressionType>
|
||||||
{
|
{};
|
||||||
enum {
|
|
||||||
Flags = traits<ExpressionType>::Flags & ~NestByRefBit
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \class NestByValue
|
/** \class NestByValue
|
||||||
@@ -45,13 +41,57 @@ template<typename ExpressionType> class NestByValue
|
|||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit inline NestByValue(const ExpressionType& matrix) : m_expression(matrix) {}
|
EIGEN_DEVICE_FUNC explicit inline NestByValue(const ExpressionType& matrix) : m_expression(matrix) {}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index rows() const EIGEN_NOEXCEPT { return m_expression.rows(); }
|
EIGEN_DEVICE_FUNC inline Index rows() const { return m_expression.rows(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index cols() const EIGEN_NOEXCEPT { return m_expression.cols(); }
|
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 const CoeffReturnType coeff(Index row, Index col) const
|
||||||
|
{
|
||||||
|
return m_expression.coeff(row, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index row, Index col)
|
||||||
|
{
|
||||||
|
return m_expression.const_cast_derived().coeffRef(row, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC inline const 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
inline const PacketScalar packet(Index row, Index col) const
|
||||||
|
{
|
||||||
|
return m_expression.template packet<LoadMode>(row, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
inline void writePacket(Index row, Index col, const PacketScalar& x)
|
||||||
|
{
|
||||||
|
m_expression.const_cast_derived().template writePacket<LoadMode>(row, col, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
inline const PacketScalar packet(Index index) const
|
||||||
|
{
|
||||||
|
return m_expression.template packet<LoadMode>(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
inline void writePacket(Index index, const PacketScalar& x)
|
||||||
|
{
|
||||||
|
m_expression.const_cast_derived().template writePacket<LoadMode>(index, x);
|
||||||
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC operator const ExpressionType&() const { return m_expression; }
|
EIGEN_DEVICE_FUNC operator const ExpressionType&() const { return m_expression; }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC const ExpressionType& nestedExpression() const { return m_expression; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const ExpressionType m_expression;
|
const ExpressionType m_expression;
|
||||||
};
|
};
|
||||||
@@ -65,21 +105,6 @@ DenseBase<Derived>::nestByValue() const
|
|||||||
return NestByValue<Derived>(derived());
|
return NestByValue<Derived>(derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
// Evaluator of Solve -> eval into a temporary
|
|
||||||
template<typename ArgType>
|
|
||||||
struct evaluator<NestByValue<ArgType> >
|
|
||||||
: public evaluator<ArgType>
|
|
||||||
{
|
|
||||||
typedef evaluator<ArgType> Base;
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit evaluator(const NestByValue<ArgType>& xpr)
|
|
||||||
: Base(xpr.nestedExpression())
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_NESTBYVALUE_H
|
#endif // EIGEN_NESTBYVALUE_H
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ class NoAlias
|
|||||||
public:
|
public:
|
||||||
typedef typename ExpressionType::Scalar Scalar;
|
typedef typename ExpressionType::Scalar Scalar;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
explicit NoAlias(ExpressionType& expression) : m_expression(expression) {}
|
explicit NoAlias(ExpressionType& expression) : m_expression(expression) {}
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
@@ -75,10 +74,10 @@ class NoAlias
|
|||||||
*
|
*
|
||||||
* More precisely, noalias() allows to bypass the EvalBeforeAssignBit flag.
|
* More precisely, noalias() allows to bypass the EvalBeforeAssignBit flag.
|
||||||
* Currently, even though several expressions may alias, only product
|
* Currently, even though several expressions may alias, only product
|
||||||
* expressions have this flag. Therefore, noalias() is only useful when
|
* expressions have this flag. Therefore, noalias() is only usefull when
|
||||||
* the source expression contains a matrix product.
|
* the source expression contains a matrix product.
|
||||||
*
|
*
|
||||||
* Here are some examples where noalias is useful:
|
* Here are some examples where noalias is usefull:
|
||||||
* \code
|
* \code
|
||||||
* D.noalias() = A * B;
|
* D.noalias() = A * B;
|
||||||
* D.noalias() += A.transpose() * B;
|
* D.noalias() += A.transpose() * B;
|
||||||
@@ -99,7 +98,7 @@ class NoAlias
|
|||||||
* \sa class NoAlias
|
* \sa class NoAlias
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
NoAlias<Derived,MatrixBase> EIGEN_DEVICE_FUNC MatrixBase<Derived>::noalias()
|
NoAlias<Derived,MatrixBase> MatrixBase<Derived>::noalias()
|
||||||
{
|
{
|
||||||
return NoAlias<Derived, Eigen::MatrixBase >(derived());
|
return NoAlias<Derived, Eigen::MatrixBase >(derived());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,14 +21,12 @@ template< typename T,
|
|||||||
bool is_integer = NumTraits<T>::IsInteger>
|
bool is_integer = NumTraits<T>::IsInteger>
|
||||||
struct default_digits10_impl
|
struct default_digits10_impl
|
||||||
{
|
{
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
|
||||||
static int run() { return std::numeric_limits<T>::digits10; }
|
static int run() { return std::numeric_limits<T>::digits10; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct default_digits10_impl<T,false,false> // Floating point
|
struct default_digits10_impl<T,false,false> // Floating point
|
||||||
{
|
{
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
|
||||||
static int run() {
|
static int run() {
|
||||||
using std::log10;
|
using std::log10;
|
||||||
using std::ceil;
|
using std::ceil;
|
||||||
@@ -40,65 +38,11 @@ struct default_digits10_impl<T,false,false> // Floating point
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
struct default_digits10_impl<T,false,true> // Integer
|
struct default_digits10_impl<T,false,true> // Integer
|
||||||
{
|
{
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
|
||||||
static int run() { return 0; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// default implementation of digits(), based on numeric_limits if specialized,
|
|
||||||
// 0 for integer types, and log2(epsilon()) otherwise.
|
|
||||||
template< typename T,
|
|
||||||
bool use_numeric_limits = std::numeric_limits<T>::is_specialized,
|
|
||||||
bool is_integer = NumTraits<T>::IsInteger>
|
|
||||||
struct default_digits_impl
|
|
||||||
{
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
|
||||||
static int run() { return std::numeric_limits<T>::digits; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct default_digits_impl<T,false,false> // Floating point
|
|
||||||
{
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
|
||||||
static int run() {
|
|
||||||
using std::log;
|
|
||||||
using std::ceil;
|
|
||||||
typedef typename NumTraits<T>::Real Real;
|
|
||||||
return int(ceil(-log(NumTraits<Real>::epsilon())/log(static_cast<Real>(2))));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct default_digits_impl<T,false,true> // Integer
|
|
||||||
{
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
|
||||||
static int run() { return 0; }
|
static int run() { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
namespace numext {
|
|
||||||
/** \internal bit-wise cast without changing the underlying bit representation. */
|
|
||||||
|
|
||||||
// TODO: Replace by std::bit_cast (available in C++20)
|
|
||||||
template <typename Tgt, typename Src>
|
|
||||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Tgt bit_cast(const Src& src) {
|
|
||||||
#if EIGEN_HAS_TYPE_TRAITS
|
|
||||||
// The behaviour of memcpy is not specified for non-trivially copyable types
|
|
||||||
EIGEN_STATIC_ASSERT(std::is_trivially_copyable<Src>::value, THIS_TYPE_IS_NOT_SUPPORTED);
|
|
||||||
EIGEN_STATIC_ASSERT(std::is_trivially_copyable<Tgt>::value && std::is_default_constructible<Tgt>::value,
|
|
||||||
THIS_TYPE_IS_NOT_SUPPORTED);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
EIGEN_STATIC_ASSERT(sizeof(Src) == sizeof(Tgt), THIS_TYPE_IS_NOT_SUPPORTED);
|
|
||||||
Tgt tgt;
|
|
||||||
EIGEN_USING_STD(memcpy)
|
|
||||||
memcpy(&tgt, &src, sizeof(Tgt));
|
|
||||||
return tgt;
|
|
||||||
}
|
|
||||||
} // namespace numext
|
|
||||||
|
|
||||||
// clang-format off
|
|
||||||
/** \class NumTraits
|
/** \class NumTraits
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
*
|
*
|
||||||
@@ -114,43 +58,32 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Tgt bit_cast(const Src& src) {
|
|||||||
* is a typedef to \a U.
|
* is a typedef to \a U.
|
||||||
* \li A typedef \c NonInteger, giving the type that should be used for operations producing non-integral values,
|
* \li A typedef \c NonInteger, giving the type that should be used for operations producing non-integral values,
|
||||||
* such as quotients, square roots, etc. If \a T is a floating-point type, then this typedef just gives
|
* such as quotients, square roots, etc. If \a T is a floating-point type, then this typedef just gives
|
||||||
* \a T again. Note however that many Eigen functions such as `internal::sqrt` simply refuse to
|
* \a T again. Note however that many Eigen functions such as internal::sqrt simply refuse to
|
||||||
* take integers. Outside of a few cases, Eigen doesn't do automatic type promotion. Thus, this typedef is
|
* take integers. Outside of a few cases, Eigen doesn't do automatic type promotion. Thus, this typedef is
|
||||||
* only intended as a helper for code that needs to explicitly promote types.
|
* only intended as a helper for code that needs to explicitly promote types.
|
||||||
* \li A typedef \c Literal giving the type to use for numeric literals such as "2" or "0.5". For instance, for `std::complex<U>`,
|
* \li A typedef \c Literal giving the type to use for numeric literals such as "2" or "0.5". For instance, for `std::complex<U>`, Literal is defined as \c U.
|
||||||
* Literal is defined as \c U.
|
|
||||||
* Of course, this type must be fully compatible with \a T. In doubt, just use \a T here.
|
* Of course, this type must be fully compatible with \a T. In doubt, just use \a T here.
|
||||||
* \li A typedef \c Nested giving the type to use to nest a value inside of the expression tree. If you don't know what
|
* \li A typedef \c Nested giving the type to use to nest a value inside of the expression tree. If you don't know what
|
||||||
* this means, just use \a T here.
|
* this means, just use \a T here.
|
||||||
* \li An enum value \c IsComplex. It is equal to 1 if \a T is a \c std::complex
|
* \li An enum value \c IsComplex. It is equal to 1 if \a T is a `std::complex`
|
||||||
* type, and to 0 otherwise.
|
* type, and to 0 otherwise.
|
||||||
* \li An enum value \c IsInteger. It is equal to \c 1 if \a T is an integer type such as \c int,
|
* \li An enum value \c IsInteger. It is equal to \c 1 if \a T is an integer type such as \c int,
|
||||||
* and to \c 0 otherwise.
|
* and to \c 0 otherwise.
|
||||||
* \li Enum values \c ReadCost, \c AddCost and \c MulCost representing a rough estimate of the number of CPU cycles needed
|
* \li Enum values \c ReadCost, \c AddCost and \c MulCost representing a rough estimate of the number of CPU cycles needed
|
||||||
* to by move / add / mul instructions respectively, assuming the data is already stored in CPU registers.
|
* to by move / add / mul instructions respectively, assuming the data is already stored in CPU registers.
|
||||||
* Stay vague here. No need to do architecture-specific stuff. If you don't know what this means, just use \c Eigen::HugeCost.
|
* Stay vague here. No need to do architecture-specific stuff.
|
||||||
* \li An enum value \c IsSigned. It is equal to \c 1 if \a T is a signed type and to 0 if \a T is unsigned.
|
* \li An enum value \c IsSigned. It is equal to \c 1 if \a T is a signed type and to 0 if \a T is unsigned.
|
||||||
* \li An enum value \c RequireInitialization. It is equal to \c 1 if the constructor of the numeric type \a T must
|
* \li An enum value \c RequireInitialization. It is equal to \c 1 if the constructor of the numeric type \a T must
|
||||||
* be called, and to 0 if it is safe not to call it. Default is 0 if \a T is an arithmetic type, and 1 otherwise.
|
* be called, and to 0 if it is safe not to call it. Default is 0 if \a T is an arithmetic type, and 1 otherwise.
|
||||||
* \li An `epsilon()` function which, unlike <a href="http://en.cppreference.com/w/cpp/types/numeric_limits/epsilon">`std::numeric_limits::epsilon()`</a>,
|
* \li An `epsilon()` function which, unlike <a href="http://en.cppreference.com/w/cpp/types/numeric_limits/epsilon">`std::numeric_limits::epsilon()`</a>,
|
||||||
* it returns a \c Real instead of a \a T.
|
* it returns a \a Real instead of a \a T.
|
||||||
* \li A `dummy_precision()` function returning a weak epsilon value. It is mainly used as a default
|
* \li A `dummy_precision()` function returning a weak epsilon value. It is mainly used as a default
|
||||||
* value by the fuzzy comparison operators.
|
* value by the fuzzy comparison operators.
|
||||||
* \li `highest()` and `lowest()` functions returning the highest and lowest possible values respectively.
|
* \li `highest()` and `lowest()` functions returning the highest and lowest possible values respectively.
|
||||||
* \li `digits()` function returning the number of radix digits (non-sign digits for integers, mantissa for floating-point). This is
|
|
||||||
* the analogue of <a href="http://en.cppreference.com/w/cpp/types/numeric_limits/digits">std::numeric_limits<T>::digits</a>
|
|
||||||
* which is used as the default implementation if specialized.
|
|
||||||
* \li `digits10()` function returning the number of decimal digits that can be represented without change. This is
|
* \li `digits10()` function returning the number of decimal digits that can be represented without change. This is
|
||||||
* the analogue of <a href="http://en.cppreference.com/w/cpp/types/numeric_limits/digits10">std::numeric_limits<T>::digits10</a>
|
* the analogue of <a href="http://en.cppreference.com/w/cpp/types/numeric_limits/digits10">`std::numeric_limits<T>::digits10`</a>
|
||||||
* which is used as the default implementation if specialized.
|
* which is used as the default implementation if specialized.
|
||||||
* \li `min_exponent()` and `max_exponent()` functions returning the highest and lowest possible values, respectively,
|
|
||||||
* such that the radix raised to the power exponent-1 is a normalized floating-point number. These are equivalent to
|
|
||||||
* <a href="http://en.cppreference.com/w/cpp/types/numeric_limits/min_exponent">`std::numeric_limits<T>::min_exponent`</a>/
|
|
||||||
* <a href="http://en.cppreference.com/w/cpp/types/numeric_limits/max_exponent">`std::numeric_limits<T>::max_exponent`</a>.
|
|
||||||
* \li `infinity()` function returning a representation of positive infinity, if available.
|
|
||||||
* \li `quiet_NaN` function returning a non-signaling "not-a-number", if available.
|
|
||||||
*/
|
*/
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
template<typename T> struct GenericNumTraits
|
template<typename T> struct GenericNumTraits
|
||||||
{
|
{
|
||||||
@@ -173,60 +106,42 @@ template<typename T> struct GenericNumTraits
|
|||||||
typedef T Nested;
|
typedef T Nested;
|
||||||
typedef T Literal;
|
typedef T Literal;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
static inline Real epsilon()
|
static inline Real epsilon()
|
||||||
{
|
{
|
||||||
return numext::numeric_limits<T>::epsilon();
|
return numext::numeric_limits<T>::epsilon();
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
static inline int digits10()
|
static inline int digits10()
|
||||||
{
|
{
|
||||||
return internal::default_digits10_impl<T>::run();
|
return internal::default_digits10_impl<T>::run();
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
static inline int digits()
|
|
||||||
{
|
|
||||||
return internal::default_digits_impl<T>::run();
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
|
||||||
static inline int min_exponent()
|
|
||||||
{
|
|
||||||
return numext::numeric_limits<T>::min_exponent;
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
|
||||||
static inline int max_exponent()
|
|
||||||
{
|
|
||||||
return numext::numeric_limits<T>::max_exponent;
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
|
||||||
static inline Real dummy_precision()
|
static inline Real dummy_precision()
|
||||||
{
|
{
|
||||||
// make sure to override this for floating-point types
|
// make sure to override this for floating-point types
|
||||||
return Real(0);
|
return Real(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
static inline T highest() {
|
static inline T highest() {
|
||||||
return (numext::numeric_limits<T>::max)();
|
return (numext::numeric_limits<T>::max)();
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
static inline T lowest() {
|
static inline T lowest() {
|
||||||
return IsInteger ? (numext::numeric_limits<T>::min)()
|
return IsInteger ? (numext::numeric_limits<T>::min)() : (-(numext::numeric_limits<T>::max)());
|
||||||
: static_cast<T>(-(numext::numeric_limits<T>::max)());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
static inline T infinity() {
|
static inline T infinity() {
|
||||||
return numext::numeric_limits<T>::infinity();
|
return numext::numeric_limits<T>::infinity();
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
static inline T quiet_NaN() {
|
static inline T quiet_NaN() {
|
||||||
return numext::numeric_limits<T>::quiet_NaN();
|
return numext::numeric_limits<T>::quiet_NaN();
|
||||||
}
|
}
|
||||||
@@ -238,27 +153,23 @@ template<typename T> struct NumTraits : GenericNumTraits<T>
|
|||||||
template<> struct NumTraits<float>
|
template<> struct NumTraits<float>
|
||||||
: GenericNumTraits<float>
|
: GenericNumTraits<float>
|
||||||
{
|
{
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
static inline float dummy_precision() { return 1e-5f; }
|
static inline float dummy_precision() { return 1e-5f; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> struct NumTraits<double> : GenericNumTraits<double>
|
template<> struct NumTraits<double> : GenericNumTraits<double>
|
||||||
{
|
{
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
static inline double dummy_precision() { return 1e-12; }
|
static inline double dummy_precision() { return 1e-12; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// GPU devices treat `long double` as `double`.
|
|
||||||
#ifndef EIGEN_GPU_COMPILE_PHASE
|
|
||||||
template<> struct NumTraits<long double>
|
template<> struct NumTraits<long double>
|
||||||
: GenericNumTraits<long double>
|
: GenericNumTraits<long double>
|
||||||
{
|
{
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
|
||||||
static inline long double dummy_precision() { return static_cast<long double>(1e-15l); }
|
static inline long double dummy_precision() { return static_cast<long double>(1e-15l); }
|
||||||
|
|
||||||
#if defined(EIGEN_ARCH_PPC) && (__LDBL_MANT_DIG__ == 106)
|
#if defined(EIGEN_ARCH_PPC) && (__LDBL_MANT_DIG__ == 106)
|
||||||
// PowerPC double double causes issues with some values
|
// PowerPC double double causes issues with some values
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
|
||||||
static inline long double epsilon()
|
static inline long double epsilon()
|
||||||
{
|
{
|
||||||
// 2^(-(__LDBL_MANT_DIG__)+1)
|
// 2^(-(__LDBL_MANT_DIG__)+1)
|
||||||
@@ -266,7 +177,6 @@ template<> struct NumTraits<long double>
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename _Real> struct NumTraits<std::complex<_Real> >
|
template<typename _Real> struct NumTraits<std::complex<_Real> >
|
||||||
: GenericNumTraits<std::complex<_Real> >
|
: GenericNumTraits<std::complex<_Real> >
|
||||||
@@ -281,11 +191,11 @@ template<typename _Real> struct NumTraits<std::complex<_Real> >
|
|||||||
MulCost = 4 * NumTraits<Real>::MulCost + 2 * NumTraits<Real>::AddCost
|
MulCost = 4 * NumTraits<Real>::MulCost + 2 * NumTraits<Real>::AddCost
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
static inline Real epsilon() { return NumTraits<Real>::epsilon(); }
|
static inline Real epsilon() { return NumTraits<Real>::epsilon(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
static inline Real dummy_precision() { return NumTraits<Real>::dummy_precision(); }
|
static inline Real dummy_precision() { return NumTraits<Real>::dummy_precision(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
static inline int digits10() { return NumTraits<Real>::digits10(); }
|
static inline int digits10() { return NumTraits<Real>::digits10(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -305,17 +215,16 @@ struct NumTraits<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
|
|||||||
IsInteger = NumTraits<Scalar>::IsInteger,
|
IsInteger = NumTraits<Scalar>::IsInteger,
|
||||||
IsSigned = NumTraits<Scalar>::IsSigned,
|
IsSigned = NumTraits<Scalar>::IsSigned,
|
||||||
RequireInitialization = 1,
|
RequireInitialization = 1,
|
||||||
ReadCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * int(NumTraits<Scalar>::ReadCost),
|
ReadCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::ReadCost,
|
||||||
AddCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * int(NumTraits<Scalar>::AddCost),
|
AddCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::AddCost,
|
||||||
MulCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * int(NumTraits<Scalar>::MulCost)
|
MulCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::MulCost
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
static inline RealScalar epsilon() { return NumTraits<RealScalar>::epsilon(); }
|
static inline RealScalar epsilon() { return NumTraits<RealScalar>::epsilon(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
static inline RealScalar dummy_precision() { return NumTraits<RealScalar>::dummy_precision(); }
|
static inline RealScalar dummy_precision() { return NumTraits<RealScalar>::dummy_precision(); }
|
||||||
|
|
||||||
EIGEN_CONSTEXPR
|
|
||||||
static inline int digits10() { return NumTraits<Scalar>::digits10(); }
|
static inline int digits10() { return NumTraits<Scalar>::digits10(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -329,7 +238,6 @@ template<> struct NumTraits<std::string>
|
|||||||
MulCost = HugeCost
|
MulCost = HugeCost
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_CONSTEXPR
|
|
||||||
static inline int digits10() { return 0; }
|
static inline int digits10() { return 0; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -344,8 +252,6 @@ private:
|
|||||||
// Empty specialization for void to allow template specialization based on NumTraits<T>::Real with T==void and SFINAE.
|
// Empty specialization for void to allow template specialization based on NumTraits<T>::Real with T==void and SFINAE.
|
||||||
template<> struct NumTraits<void> {};
|
template<> struct NumTraits<void> {};
|
||||||
|
|
||||||
template<> struct NumTraits<bool> : GenericNumTraits<bool> {};
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_NUMTRAITS_H
|
#endif // EIGEN_NUMTRAITS_H
|
||||||
|
|||||||
@@ -1,237 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2011-2018 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_PARTIALREDUX_H
|
|
||||||
#define EIGEN_PARTIALREDUX_H
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
*
|
|
||||||
* This file provides evaluators for partial reductions.
|
|
||||||
* There are two modes:
|
|
||||||
*
|
|
||||||
* - scalar path: simply calls the respective function on the column or row.
|
|
||||||
* -> nothing special here, all the tricky part is handled by the return
|
|
||||||
* types of VectorwiseOp's members. They embed the functor calling the
|
|
||||||
* respective DenseBase's member function.
|
|
||||||
*
|
|
||||||
* - vectorized path: implements a packet-wise reductions followed by
|
|
||||||
* some (optional) processing of the outcome, e.g., division by n for mean.
|
|
||||||
*
|
|
||||||
* For the vectorized path let's observe that the packet-size and outer-unrolling
|
|
||||||
* are both decided by the assignement logic. So all we have to do is to decide
|
|
||||||
* on the inner unrolling.
|
|
||||||
*
|
|
||||||
* For the unrolling, we can reuse "internal::redux_vec_unroller" from Redux.h,
|
|
||||||
* but be need to be careful to specify correct increment.
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
/* logic deciding a strategy for unrolling of vectorized paths */
|
|
||||||
template<typename Func, typename Evaluator>
|
|
||||||
struct packetwise_redux_traits
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
OuterSize = int(Evaluator::IsRowMajor) ? Evaluator::RowsAtCompileTime : Evaluator::ColsAtCompileTime,
|
|
||||||
Cost = OuterSize == Dynamic ? HugeCost
|
|
||||||
: OuterSize * Evaluator::CoeffReadCost + (OuterSize-1) * functor_traits<Func>::Cost,
|
|
||||||
Unrolling = Cost <= EIGEN_UNROLLING_LIMIT ? CompleteUnrolling : NoUnrolling
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Value to be returned when size==0 , by default let's return 0 */
|
|
||||||
template<typename PacketType,typename Func>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
PacketType packetwise_redux_empty_value(const Func& ) {
|
|
||||||
const typename unpacket_traits<PacketType>::type zero(0);
|
|
||||||
return pset1<PacketType>(zero);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For products the default is 1 */
|
|
||||||
template<typename PacketType,typename Scalar>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
PacketType packetwise_redux_empty_value(const scalar_product_op<Scalar,Scalar>& ) {
|
|
||||||
return pset1<PacketType>(Scalar(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Perform the actual reduction */
|
|
||||||
template<typename Func, typename Evaluator,
|
|
||||||
int Unrolling = packetwise_redux_traits<Func, Evaluator>::Unrolling
|
|
||||||
>
|
|
||||||
struct packetwise_redux_impl;
|
|
||||||
|
|
||||||
/* Perform the actual reduction with unrolling */
|
|
||||||
template<typename Func, typename Evaluator>
|
|
||||||
struct packetwise_redux_impl<Func, Evaluator, CompleteUnrolling>
|
|
||||||
{
|
|
||||||
typedef redux_novec_unroller<Func,Evaluator, 0, Evaluator::SizeAtCompileTime> Base;
|
|
||||||
typedef typename Evaluator::Scalar Scalar;
|
|
||||||
|
|
||||||
template<typename PacketType>
|
|
||||||
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE
|
|
||||||
PacketType run(const Evaluator &eval, const Func& func, Index /*size*/)
|
|
||||||
{
|
|
||||||
return redux_vec_unroller<Func, Evaluator, 0, packetwise_redux_traits<Func, Evaluator>::OuterSize>::template run<PacketType>(eval,func);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Add a specialization of redux_vec_unroller for size==0 at compiletime.
|
|
||||||
* This specialization is not required for general reductions, which is
|
|
||||||
* why it is defined here.
|
|
||||||
*/
|
|
||||||
template<typename Func, typename Evaluator, int Start>
|
|
||||||
struct redux_vec_unroller<Func, Evaluator, Start, 0>
|
|
||||||
{
|
|
||||||
template<typename PacketType>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static EIGEN_STRONG_INLINE PacketType run(const Evaluator &, const Func& f)
|
|
||||||
{
|
|
||||||
return packetwise_redux_empty_value<PacketType>(f);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Perform the actual reduction for dynamic sizes */
|
|
||||||
template<typename Func, typename Evaluator>
|
|
||||||
struct packetwise_redux_impl<Func, Evaluator, NoUnrolling>
|
|
||||||
{
|
|
||||||
typedef typename Evaluator::Scalar Scalar;
|
|
||||||
typedef typename redux_traits<Func, Evaluator>::PacketType PacketScalar;
|
|
||||||
|
|
||||||
template<typename PacketType>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static PacketType run(const Evaluator &eval, const Func& func, Index size)
|
|
||||||
{
|
|
||||||
if(size==0)
|
|
||||||
return packetwise_redux_empty_value<PacketType>(func);
|
|
||||||
|
|
||||||
const Index size4 = (size-1)&(~3);
|
|
||||||
PacketType p = eval.template packetByOuterInner<Unaligned,PacketType>(0,0);
|
|
||||||
Index i = 1;
|
|
||||||
// This loop is optimized for instruction pipelining:
|
|
||||||
// - each iteration generates two independent instructions
|
|
||||||
// - thanks to branch prediction and out-of-order execution we have independent instructions across loops
|
|
||||||
for(; i<size4; i+=4)
|
|
||||||
p = func.packetOp(p,
|
|
||||||
func.packetOp(
|
|
||||||
func.packetOp(eval.template packetByOuterInner<Unaligned,PacketType>(i+0,0),eval.template packetByOuterInner<Unaligned,PacketType>(i+1,0)),
|
|
||||||
func.packetOp(eval.template packetByOuterInner<Unaligned,PacketType>(i+2,0),eval.template packetByOuterInner<Unaligned,PacketType>(i+3,0))));
|
|
||||||
for(; i<size; ++i)
|
|
||||||
p = func.packetOp(p, eval.template packetByOuterInner<Unaligned,PacketType>(i,0));
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template< typename ArgType, typename MemberOp, int Direction>
|
|
||||||
struct evaluator<PartialReduxExpr<ArgType, MemberOp, Direction> >
|
|
||||||
: evaluator_base<PartialReduxExpr<ArgType, MemberOp, Direction> >
|
|
||||||
{
|
|
||||||
typedef PartialReduxExpr<ArgType, MemberOp, Direction> XprType;
|
|
||||||
typedef typename internal::nested_eval<ArgType,1>::type ArgTypeNested;
|
|
||||||
typedef typename internal::add_const_on_value_type<ArgTypeNested>::type ConstArgTypeNested;
|
|
||||||
typedef typename internal::remove_all<ArgTypeNested>::type ArgTypeNestedCleaned;
|
|
||||||
typedef typename ArgType::Scalar InputScalar;
|
|
||||||
typedef typename XprType::Scalar Scalar;
|
|
||||||
enum {
|
|
||||||
TraversalSize = Direction==int(Vertical) ? int(ArgType::RowsAtCompileTime) : int(ArgType::ColsAtCompileTime)
|
|
||||||
};
|
|
||||||
typedef typename MemberOp::template Cost<int(TraversalSize)> CostOpType;
|
|
||||||
enum {
|
|
||||||
CoeffReadCost = TraversalSize==Dynamic ? HugeCost
|
|
||||||
: TraversalSize==0 ? 1
|
|
||||||
: int(TraversalSize) * int(evaluator<ArgType>::CoeffReadCost) + int(CostOpType::value),
|
|
||||||
|
|
||||||
_ArgFlags = evaluator<ArgType>::Flags,
|
|
||||||
|
|
||||||
_Vectorizable = bool(int(_ArgFlags)&PacketAccessBit)
|
|
||||||
&& bool(MemberOp::Vectorizable)
|
|
||||||
&& (Direction==int(Vertical) ? bool(_ArgFlags&RowMajorBit) : (_ArgFlags&RowMajorBit)==0)
|
|
||||||
&& (TraversalSize!=0),
|
|
||||||
|
|
||||||
Flags = (traits<XprType>::Flags&RowMajorBit)
|
|
||||||
| (evaluator<ArgType>::Flags&(HereditaryBits&(~RowMajorBit)))
|
|
||||||
| (_Vectorizable ? PacketAccessBit : 0)
|
|
||||||
| LinearAccessBit,
|
|
||||||
|
|
||||||
Alignment = 0 // FIXME this will need to be improved once PartialReduxExpr is vectorized
|
|
||||||
};
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit evaluator(const XprType xpr)
|
|
||||||
: m_arg(xpr.nestedExpression()), m_functor(xpr.functor())
|
|
||||||
{
|
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(TraversalSize==Dynamic ? HugeCost : (TraversalSize==0 ? 1 : int(CostOpType::value)));
|
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
const Scalar coeff(Index i, Index j) const
|
|
||||||
{
|
|
||||||
return coeff(Direction==Vertical ? j : i);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
const Scalar coeff(Index index) const
|
|
||||||
{
|
|
||||||
return m_functor(m_arg.template subVector<DirectionType(Direction)>(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int LoadMode,typename PacketType>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
PacketType packet(Index i, Index j) const
|
|
||||||
{
|
|
||||||
return packet<LoadMode,PacketType>(Direction==Vertical ? j : i);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int LoadMode,typename PacketType>
|
|
||||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
|
|
||||||
PacketType packet(Index idx) const
|
|
||||||
{
|
|
||||||
enum { PacketSize = internal::unpacket_traits<PacketType>::size };
|
|
||||||
typedef Block<const ArgTypeNestedCleaned,
|
|
||||||
Direction==Vertical ? int(ArgType::RowsAtCompileTime) : int(PacketSize),
|
|
||||||
Direction==Vertical ? int(PacketSize) : int(ArgType::ColsAtCompileTime),
|
|
||||||
true /* InnerPanel */> PanelType;
|
|
||||||
|
|
||||||
PanelType panel(m_arg,
|
|
||||||
Direction==Vertical ? 0 : idx,
|
|
||||||
Direction==Vertical ? idx : 0,
|
|
||||||
Direction==Vertical ? m_arg.rows() : Index(PacketSize),
|
|
||||||
Direction==Vertical ? Index(PacketSize) : m_arg.cols());
|
|
||||||
|
|
||||||
// FIXME
|
|
||||||
// See bug 1612, currently if PacketSize==1 (i.e. complex<double> with 128bits registers) then the storage-order of panel get reversed
|
|
||||||
// and methods like packetByOuterInner do not make sense anymore in this context.
|
|
||||||
// So let's just by pass "vectorization" in this case:
|
|
||||||
if(PacketSize==1)
|
|
||||||
return internal::pset1<PacketType>(coeff(idx));
|
|
||||||
|
|
||||||
typedef typename internal::redux_evaluator<PanelType> PanelEvaluator;
|
|
||||||
PanelEvaluator panel_eval(panel);
|
|
||||||
typedef typename MemberOp::BinaryOp BinaryOp;
|
|
||||||
PacketType p = internal::packetwise_redux_impl<BinaryOp,PanelEvaluator>::template run<PacketType>(panel_eval,m_functor.binaryFunc(),m_arg.outerSize());
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ConstArgTypeNested m_arg;
|
|
||||||
const MemberOp m_functor;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_PARTIALREDUX_H
|
|
||||||
@@ -88,13 +88,13 @@ class PermutationBase : public EigenBase<Derived>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the number of rows */
|
/** \returns the number of rows */
|
||||||
inline EIGEN_DEVICE_FUNC Index rows() const { return Index(indices().size()); }
|
inline Index rows() const { return Index(indices().size()); }
|
||||||
|
|
||||||
/** \returns the number of columns */
|
/** \returns the number of columns */
|
||||||
inline EIGEN_DEVICE_FUNC Index cols() const { return Index(indices().size()); }
|
inline Index cols() const { return Index(indices().size()); }
|
||||||
|
|
||||||
/** \returns the size of a side of the respective square matrix, i.e., the number of indices */
|
/** \returns the size of a side of the respective square matrix, i.e., the number of indices */
|
||||||
inline EIGEN_DEVICE_FUNC Index size() const { return Index(indices().size()); }
|
inline Index size() const { return Index(indices().size()); }
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
template<typename DenseDerived>
|
template<typename DenseDerived>
|
||||||
|
|||||||
@@ -13,10 +13,10 @@
|
|||||||
|
|
||||||
#if defined(EIGEN_INITIALIZE_MATRICES_BY_ZERO)
|
#if defined(EIGEN_INITIALIZE_MATRICES_BY_ZERO)
|
||||||
# define EIGEN_INITIALIZE_COEFFS
|
# define EIGEN_INITIALIZE_COEFFS
|
||||||
# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED for(Index i=0;i<base().size();++i) coeffRef(i)=Scalar(0);
|
# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=Scalar(0);
|
||||||
#elif defined(EIGEN_INITIALIZE_MATRICES_BY_NAN)
|
#elif defined(EIGEN_INITIALIZE_MATRICES_BY_NAN)
|
||||||
# define EIGEN_INITIALIZE_COEFFS
|
# define EIGEN_INITIALIZE_COEFFS
|
||||||
# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED for(Index i=0;i<base().size();++i) coeffRef(i)=std::numeric_limits<Scalar>::quiet_NaN();
|
# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=std::numeric_limits<Scalar>::quiet_NaN();
|
||||||
#else
|
#else
|
||||||
# undef EIGEN_INITIALIZE_COEFFS
|
# undef EIGEN_INITIALIZE_COEFFS
|
||||||
# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
|
# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
|
||||||
@@ -118,8 +118,16 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||||||
using Base::IsVectorAtCompileTime;
|
using Base::IsVectorAtCompileTime;
|
||||||
using Base::Flags;
|
using Base::Flags;
|
||||||
|
|
||||||
|
template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map;
|
||||||
|
friend class Eigen::Map<Derived, Unaligned>;
|
||||||
typedef Eigen::Map<Derived, Unaligned> MapType;
|
typedef Eigen::Map<Derived, Unaligned> MapType;
|
||||||
|
friend class Eigen::Map<const Derived, Unaligned>;
|
||||||
typedef const Eigen::Map<const Derived, Unaligned> ConstMapType;
|
typedef const Eigen::Map<const Derived, Unaligned> ConstMapType;
|
||||||
|
#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 Eigen::Map<Derived, AlignedMax> AlignedMapType;
|
||||||
typedef const Eigen::Map<const Derived, AlignedMax> ConstAlignedMapType;
|
typedef const Eigen::Map<const Derived, AlignedMax> ConstAlignedMapType;
|
||||||
template<typename StrideType> struct StridedMapType { typedef Eigen::Map<Derived, Unaligned, StrideType> type; };
|
template<typename StrideType> struct StridedMapType { typedef Eigen::Map<Derived, Unaligned, StrideType> type; };
|
||||||
@@ -139,10 +147,10 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const Base& base() const { return *static_cast<const Base*>(this); }
|
const Base& base() const { return *static_cast<const Base*>(this); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
Index rows() const EIGEN_NOEXCEPT { return m_storage.rows(); }
|
EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
Index cols() const EIGEN_NOEXCEPT { return m_storage.cols(); }
|
EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); }
|
||||||
|
|
||||||
/** This is an overloaded version of DenseCoeffsBase<Derived,ReadOnlyAccessors>::coeff(Index,Index) const
|
/** This is an overloaded version of DenseCoeffsBase<Derived,ReadOnlyAccessors>::coeff(Index,Index) const
|
||||||
* provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts.
|
* provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts.
|
||||||
@@ -500,8 +508,8 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
PlainObjectBase& operator=(PlainObjectBase&& other) EIGEN_NOEXCEPT
|
PlainObjectBase& operator=(PlainObjectBase&& other) EIGEN_NOEXCEPT
|
||||||
{
|
{
|
||||||
_check_template_params();
|
using std::swap;
|
||||||
m_storage = std::move(other.m_storage);
|
swap(m_storage, other.m_storage);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -518,71 +526,6 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||||||
// EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
|
// EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
|
||||||
}
|
}
|
||||||
|
|
||||||
#if EIGEN_HAS_CXX11
|
|
||||||
/** \brief Construct a row of column vector with fixed size from an arbitrary number of coefficients. \cpp11
|
|
||||||
*
|
|
||||||
* \only_for_vectors
|
|
||||||
*
|
|
||||||
* This constructor is for 1D array or vectors with more than 4 coefficients.
|
|
||||||
* There exists C++98 analogue constructors for fixed-size array/vector having 1, 2, 3, or 4 coefficients.
|
|
||||||
*
|
|
||||||
* \warning To construct a column (resp. row) vector of fixed length, the number of values passed to this
|
|
||||||
* constructor must match the the fixed number of rows (resp. columns) of \c *this.
|
|
||||||
*/
|
|
||||||
template <typename... ArgTypes>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
PlainObjectBase(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args)
|
|
||||||
: m_storage()
|
|
||||||
{
|
|
||||||
_check_template_params();
|
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, sizeof...(args) + 4);
|
|
||||||
m_storage.data()[0] = a0;
|
|
||||||
m_storage.data()[1] = a1;
|
|
||||||
m_storage.data()[2] = a2;
|
|
||||||
m_storage.data()[3] = a3;
|
|
||||||
Index i = 4;
|
|
||||||
auto x = {(m_storage.data()[i++] = args, 0)...};
|
|
||||||
static_cast<void>(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief Constructs a Matrix or Array and initializes it by elements given by an initializer list of initializer
|
|
||||||
* lists \cpp11
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
explicit EIGEN_STRONG_INLINE PlainObjectBase(const std::initializer_list<std::initializer_list<Scalar>>& list)
|
|
||||||
: m_storage()
|
|
||||||
{
|
|
||||||
_check_template_params();
|
|
||||||
|
|
||||||
size_t list_size = 0;
|
|
||||||
if (list.begin() != list.end()) {
|
|
||||||
list_size = list.begin()->size();
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is to allow syntax like VectorXi {{1, 2, 3, 4}}
|
|
||||||
if (ColsAtCompileTime == 1 && list.size() == 1) {
|
|
||||||
eigen_assert(list_size == static_cast<size_t>(RowsAtCompileTime) || RowsAtCompileTime == Dynamic);
|
|
||||||
resize(list_size, ColsAtCompileTime);
|
|
||||||
std::copy(list.begin()->begin(), list.begin()->end(), m_storage.data());
|
|
||||||
} else {
|
|
||||||
eigen_assert(list.size() == static_cast<size_t>(RowsAtCompileTime) || RowsAtCompileTime == Dynamic);
|
|
||||||
eigen_assert(list_size == static_cast<size_t>(ColsAtCompileTime) || ColsAtCompileTime == Dynamic);
|
|
||||||
resize(list.size(), list_size);
|
|
||||||
|
|
||||||
Index row_index = 0;
|
|
||||||
for (const std::initializer_list<Scalar>& row : list) {
|
|
||||||
eigen_assert(list_size == row.size());
|
|
||||||
Index col_index = 0;
|
|
||||||
for (const Scalar& e : row) {
|
|
||||||
coeffRef(row_index, col_index) = e;
|
|
||||||
++col_index;
|
|
||||||
}
|
|
||||||
++row_index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // end EIGEN_HAS_CXX11
|
|
||||||
|
|
||||||
/** \sa PlainObjectBase::operator=(const EigenBase<OtherDerived>&) */
|
/** \sa PlainObjectBase::operator=(const EigenBase<OtherDerived>&) */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
@@ -709,26 +652,18 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||||||
using Base::setConstant;
|
using Base::setConstant;
|
||||||
EIGEN_DEVICE_FUNC Derived& setConstant(Index size, const Scalar& val);
|
EIGEN_DEVICE_FUNC Derived& setConstant(Index size, const Scalar& val);
|
||||||
EIGEN_DEVICE_FUNC Derived& setConstant(Index rows, Index cols, const Scalar& val);
|
EIGEN_DEVICE_FUNC Derived& setConstant(Index rows, Index cols, const Scalar& val);
|
||||||
EIGEN_DEVICE_FUNC Derived& setConstant(NoChange_t, Index cols, const Scalar& val);
|
|
||||||
EIGEN_DEVICE_FUNC Derived& setConstant(Index rows, NoChange_t, const Scalar& val);
|
|
||||||
|
|
||||||
using Base::setZero;
|
using Base::setZero;
|
||||||
EIGEN_DEVICE_FUNC Derived& setZero(Index size);
|
EIGEN_DEVICE_FUNC Derived& setZero(Index size);
|
||||||
EIGEN_DEVICE_FUNC Derived& setZero(Index rows, Index cols);
|
EIGEN_DEVICE_FUNC Derived& setZero(Index rows, Index cols);
|
||||||
EIGEN_DEVICE_FUNC Derived& setZero(NoChange_t, Index cols);
|
|
||||||
EIGEN_DEVICE_FUNC Derived& setZero(Index rows, NoChange_t);
|
|
||||||
|
|
||||||
using Base::setOnes;
|
using Base::setOnes;
|
||||||
EIGEN_DEVICE_FUNC Derived& setOnes(Index size);
|
EIGEN_DEVICE_FUNC Derived& setOnes(Index size);
|
||||||
EIGEN_DEVICE_FUNC Derived& setOnes(Index rows, Index cols);
|
EIGEN_DEVICE_FUNC Derived& setOnes(Index rows, Index cols);
|
||||||
EIGEN_DEVICE_FUNC Derived& setOnes(NoChange_t, Index cols);
|
|
||||||
EIGEN_DEVICE_FUNC Derived& setOnes(Index rows, NoChange_t);
|
|
||||||
|
|
||||||
using Base::setRandom;
|
using Base::setRandom;
|
||||||
Derived& setRandom(Index size);
|
Derived& setRandom(Index size);
|
||||||
Derived& setRandom(Index rows, Index cols);
|
Derived& setRandom(Index rows, Index cols);
|
||||||
Derived& setRandom(NoChange_t, Index cols);
|
|
||||||
Derived& setRandom(Index rows, NoChange_t);
|
|
||||||
|
|
||||||
#ifdef EIGEN_PLAINOBJECTBASE_PLUGIN
|
#ifdef EIGEN_PLAINOBJECTBASE_PLUGIN
|
||||||
#include EIGEN_PLAINOBJECTBASE_PLUGIN
|
#include EIGEN_PLAINOBJECTBASE_PLUGIN
|
||||||
@@ -770,7 +705,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||||||
*
|
*
|
||||||
* \internal
|
* \internal
|
||||||
*/
|
*/
|
||||||
// aliasing is dealt once in internal::call_assignment
|
// aliasing is dealt once in internall::call_assignment
|
||||||
// so at this stage we have to assume aliasing... and resising has to be done later.
|
// so at this stage we have to assume aliasing... and resising has to be done later.
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
@@ -847,7 +782,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||||||
resize(size);
|
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 implicitly converted)
|
// 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>
|
template<typename T>
|
||||||
EIGEN_DEVICE_FUNC
|
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_STRONG_INLINE void _init1(const Scalar& val0, typename internal::enable_if<Base::SizeAtCompileTime==1 && internal::is_convertible<T, Scalar>::value,T>::type* = 0)
|
||||||
@@ -949,7 +884,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||||||
* of same type it is enough to swap the data pointers.
|
* of same type it is enough to swap the data pointers.
|
||||||
*/
|
*/
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
void swap(DenseBase<OtherDerived> & other)
|
void swap(DenseBase<OtherDerived> & other)
|
||||||
{
|
{
|
||||||
enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic };
|
enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic };
|
||||||
@@ -960,15 +895,15 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||||||
* \brief const version forwarded to DenseBase::swap
|
* \brief const version forwarded to DenseBase::swap
|
||||||
*/
|
*/
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
void swap(DenseBase<OtherDerived> const & other)
|
void swap(DenseBase<OtherDerived> const & other)
|
||||||
{ Base::swap(other.derived()); }
|
{ Base::swap(other.derived()); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
static EIGEN_STRONG_INLINE void _check_template_params()
|
static EIGEN_STRONG_INLINE void _check_template_params()
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (int(Options)&RowMajor)==RowMajor)
|
EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor)
|
||||||
&& EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (int(Options)&RowMajor)==0)
|
&& EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0)
|
||||||
&& ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0))
|
&& ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0))
|
||||||
&& ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0))
|
&& ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0))
|
||||||
&& ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0))
|
&& ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0))
|
||||||
@@ -980,17 +915,6 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum { IsPlainObjectBase = 1 };
|
enum { IsPlainObjectBase = 1 };
|
||||||
#endif
|
|
||||||
public:
|
|
||||||
// These apparently need to be down here for nvcc+icc to prevent duplicate
|
|
||||||
// Map symbol.
|
|
||||||
template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map;
|
|
||||||
friend class Eigen::Map<Derived, Unaligned>;
|
|
||||||
friend class Eigen::Map<const Derived, Unaligned>;
|
|
||||||
#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
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -999,19 +923,13 @@ namespace internal {
|
|||||||
template <typename Derived, typename OtherDerived, bool IsVector>
|
template <typename Derived, typename OtherDerived, bool IsVector>
|
||||||
struct conservative_resize_like_impl
|
struct conservative_resize_like_impl
|
||||||
{
|
{
|
||||||
#if EIGEN_HAS_TYPE_TRAITS
|
|
||||||
static const bool IsRelocatable = std::is_trivially_copyable<typename Derived::Scalar>::value;
|
|
||||||
#else
|
|
||||||
static const bool IsRelocatable = !NumTraits<typename Derived::Scalar>::RequireInitialization;
|
|
||||||
#endif
|
|
||||||
static void run(DenseBase<Derived>& _this, Index rows, Index cols)
|
static void run(DenseBase<Derived>& _this, Index rows, Index cols)
|
||||||
{
|
{
|
||||||
if (_this.rows() == rows && _this.cols() == cols) return;
|
if (_this.rows() == rows && _this.cols() == cols) return;
|
||||||
EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
|
EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
|
||||||
|
|
||||||
if ( IsRelocatable
|
if ( ( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows
|
||||||
&& (( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows
|
(!Derived::IsRowMajor && _this.rows() == rows) ) // column-major and we change only the number of columns
|
||||||
(!Derived::IsRowMajor && _this.rows() == rows) )) // column-major and we change only the number of columns
|
|
||||||
{
|
{
|
||||||
internal::check_rows_cols_for_overflow<Derived::MaxSizeAtCompileTime>::run(rows, cols);
|
internal::check_rows_cols_for_overflow<Derived::MaxSizeAtCompileTime>::run(rows, cols);
|
||||||
_this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
|
_this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
|
||||||
@@ -1019,7 +937,7 @@ struct conservative_resize_like_impl
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// The storage order does not allow us to use reallocation.
|
// The storage order does not allow us to use reallocation.
|
||||||
Derived tmp(rows,cols);
|
typename Derived::PlainObject tmp(rows,cols);
|
||||||
const Index common_rows = numext::mini(rows, _this.rows());
|
const Index common_rows = numext::mini(rows, _this.rows());
|
||||||
const Index common_cols = numext::mini(cols, _this.cols());
|
const Index common_cols = numext::mini(cols, _this.cols());
|
||||||
tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
|
tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
|
||||||
@@ -1039,9 +957,8 @@ struct conservative_resize_like_impl
|
|||||||
EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
|
EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
|
||||||
EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
|
EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
|
||||||
|
|
||||||
if ( IsRelocatable &&
|
if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) || // row-major and we change only the number of rows
|
||||||
(( Derived::IsRowMajor && _this.cols() == other.cols()) || // row-major and we change only the number of rows
|
(!Derived::IsRowMajor && _this.rows() == other.rows()) ) // column-major and we change only the number of columns
|
||||||
(!Derived::IsRowMajor && _this.rows() == other.rows()) )) // column-major and we change only the number of columns
|
|
||||||
{
|
{
|
||||||
const Index new_rows = other.rows() - _this.rows();
|
const Index new_rows = other.rows() - _this.rows();
|
||||||
const Index new_cols = other.cols() - _this.cols();
|
const Index new_cols = other.cols() - _this.cols();
|
||||||
@@ -1054,7 +971,7 @@ struct conservative_resize_like_impl
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// The storage order does not allow us to use reallocation.
|
// The storage order does not allow us to use reallocation.
|
||||||
Derived tmp(other);
|
typename Derived::PlainObject tmp(other);
|
||||||
const Index common_rows = numext::mini(tmp.rows(), _this.rows());
|
const Index common_rows = numext::mini(tmp.rows(), _this.rows());
|
||||||
const Index common_cols = numext::mini(tmp.cols(), _this.cols());
|
const Index common_cols = numext::mini(tmp.cols(), _this.cols());
|
||||||
tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
|
tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
|
||||||
@@ -1069,18 +986,13 @@ template <typename Derived, typename OtherDerived>
|
|||||||
struct conservative_resize_like_impl<Derived,OtherDerived,true>
|
struct conservative_resize_like_impl<Derived,OtherDerived,true>
|
||||||
: conservative_resize_like_impl<Derived,OtherDerived,false>
|
: conservative_resize_like_impl<Derived,OtherDerived,false>
|
||||||
{
|
{
|
||||||
typedef conservative_resize_like_impl<Derived,OtherDerived,false> Base;
|
using conservative_resize_like_impl<Derived,OtherDerived,false>::run;
|
||||||
using Base::run;
|
|
||||||
using Base::IsRelocatable;
|
|
||||||
|
|
||||||
static void run(DenseBase<Derived>& _this, Index size)
|
static void run(DenseBase<Derived>& _this, Index size)
|
||||||
{
|
{
|
||||||
const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size;
|
const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size;
|
||||||
const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1;
|
const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1;
|
||||||
if(IsRelocatable)
|
_this.derived().m_storage.conservativeResize(size,new_rows,new_cols);
|
||||||
_this.derived().m_storage.conservativeResize(size,new_rows,new_cols);
|
|
||||||
else
|
|
||||||
Base::run(_this.derived(), new_rows, new_cols);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
|
static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
|
||||||
@@ -1091,10 +1003,7 @@ struct conservative_resize_like_impl<Derived,OtherDerived,true>
|
|||||||
|
|
||||||
const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows();
|
const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows();
|
||||||
const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1;
|
const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1;
|
||||||
if(IsRelocatable)
|
_this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols);
|
||||||
_this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols);
|
|
||||||
else
|
|
||||||
Base::run(_this.derived(), new_rows, new_cols);
|
|
||||||
|
|
||||||
if (num_new_elements > 0)
|
if (num_new_elements > 0)
|
||||||
_this.tail(num_new_elements) = other.tail(num_new_elements);
|
_this.tail(num_new_elements) = other.tail(num_new_elements);
|
||||||
@@ -1105,7 +1014,7 @@ template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
|
|||||||
struct matrix_swap_impl
|
struct matrix_swap_impl
|
||||||
{
|
{
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
static EIGEN_STRONG_INLINE void run(MatrixTypeA& a, MatrixTypeB& b)
|
static inline void run(MatrixTypeA& a, MatrixTypeB& b)
|
||||||
{
|
{
|
||||||
a.base().swap(b);
|
a.base().swap(b);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,23 +90,18 @@ class Product : public ProductImpl<_Lhs,_Rhs,Option,
|
|||||||
typedef typename internal::remove_all<LhsNested>::type LhsNestedCleaned;
|
typedef typename internal::remove_all<LhsNested>::type LhsNestedCleaned;
|
||||||
typedef typename internal::remove_all<RhsNested>::type RhsNestedCleaned;
|
typedef typename internal::remove_all<RhsNested>::type RhsNestedCleaned;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC Product(const Lhs& lhs, const Rhs& rhs) : m_lhs(lhs), m_rhs(rhs)
|
||||||
Product(const Lhs& lhs, const Rhs& rhs) : m_lhs(lhs), m_rhs(rhs)
|
|
||||||
{
|
{
|
||||||
eigen_assert(lhs.cols() == rhs.rows()
|
eigen_assert(lhs.cols() == rhs.rows()
|
||||||
&& "invalid matrix product"
|
&& "invalid matrix product"
|
||||||
&& "if you wanted a coeff-wise or a dot product use the respective explicit functions");
|
&& "if you wanted a coeff-wise or a dot product use the respective explicit functions");
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rows() const { return m_lhs.rows(); }
|
||||||
Index rows() const EIGEN_NOEXCEPT { return m_lhs.rows(); }
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index cols() const { return m_rhs.cols(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
|
||||||
Index cols() const EIGEN_NOEXCEPT { return m_rhs.cols(); }
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC const LhsNestedCleaned& lhs() const { return m_lhs; }
|
||||||
const LhsNestedCleaned& lhs() const { return m_lhs; }
|
EIGEN_DEVICE_FUNC const RhsNestedCleaned& rhs() const { return m_rhs; }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
const RhsNestedCleaned& rhs() const { return m_rhs; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@@ -121,7 +116,7 @@ class dense_product_base
|
|||||||
: public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
|
: public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
|
||||||
{};
|
{};
|
||||||
|
|
||||||
/** Conversion to scalar for inner-products */
|
/** Convertion to scalar for inner-products */
|
||||||
template<typename Lhs, typename Rhs, int Option>
|
template<typename Lhs, typename Rhs, int Option>
|
||||||
class dense_product_base<Lhs, Rhs, Option, InnerProduct>
|
class dense_product_base<Lhs, Rhs, Option, InnerProduct>
|
||||||
: public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
|
: public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
|
||||||
@@ -132,7 +127,7 @@ public:
|
|||||||
using Base::derived;
|
using Base::derived;
|
||||||
typedef typename Base::Scalar Scalar;
|
typedef typename Base::Scalar Scalar;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE operator const Scalar() const
|
EIGEN_STRONG_INLINE operator const Scalar() const
|
||||||
{
|
{
|
||||||
return internal::evaluator<ProductXpr>(derived()).coeff(0,0);
|
return internal::evaluator<ProductXpr>(derived()).coeff(0,0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace internal {
|
|||||||
/** \internal
|
/** \internal
|
||||||
* Evaluator of a product expression.
|
* Evaluator of a product expression.
|
||||||
* Since products require special treatments to handle all possible cases,
|
* Since products require special treatments to handle all possible cases,
|
||||||
* we simply defer the evaluation logic to a product_evaluator class
|
* we simply deffer the evaluation logic to a product_evaluator class
|
||||||
* which offers more partial specialization possibilities.
|
* which offers more partial specialization possibilities.
|
||||||
*
|
*
|
||||||
* \sa class product_evaluator
|
* \sa class product_evaluator
|
||||||
@@ -128,7 +128,7 @@ protected:
|
|||||||
PlainObject m_result;
|
PlainObject m_result;
|
||||||
};
|
};
|
||||||
|
|
||||||
// The following three shortcuts are enabled only if the scalar types match exactly.
|
// The following three shortcuts are enabled only if the scalar types match excatly.
|
||||||
// TODO: we could enable them for different scalar types when the product is not vectorized.
|
// TODO: we could enable them for different scalar types when the product is not vectorized.
|
||||||
|
|
||||||
// Dense = Product
|
// Dense = Product
|
||||||
@@ -137,7 +137,7 @@ struct Assignment<DstXprType, Product<Lhs,Rhs,Options>, internal::assign_op<Scal
|
|||||||
typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct)>::type>
|
typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct)>::type>
|
||||||
{
|
{
|
||||||
typedef Product<Lhs,Rhs,Options> SrcXprType;
|
typedef Product<Lhs,Rhs,Options> SrcXprType;
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
static EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
|
||||||
void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,Scalar> &)
|
void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,Scalar> &)
|
||||||
{
|
{
|
||||||
Index dstRows = src.rows();
|
Index dstRows = src.rows();
|
||||||
@@ -155,7 +155,7 @@ struct Assignment<DstXprType, Product<Lhs,Rhs,Options>, internal::add_assign_op<
|
|||||||
typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct)>::type>
|
typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct)>::type>
|
||||||
{
|
{
|
||||||
typedef Product<Lhs,Rhs,Options> SrcXprType;
|
typedef Product<Lhs,Rhs,Options> SrcXprType;
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
static EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
|
||||||
void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<Scalar,Scalar> &)
|
void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<Scalar,Scalar> &)
|
||||||
{
|
{
|
||||||
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
|
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
|
||||||
@@ -170,7 +170,7 @@ struct Assignment<DstXprType, Product<Lhs,Rhs,Options>, internal::sub_assign_op<
|
|||||||
typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct)>::type>
|
typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct)>::type>
|
||||||
{
|
{
|
||||||
typedef Product<Lhs,Rhs,Options> SrcXprType;
|
typedef Product<Lhs,Rhs,Options> SrcXprType;
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
static EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
|
||||||
void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<Scalar,Scalar> &)
|
void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<Scalar,Scalar> &)
|
||||||
{
|
{
|
||||||
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
|
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
|
||||||
@@ -190,7 +190,7 @@ struct Assignment<DstXprType, CwiseBinaryOp<internal::scalar_product_op<ScalarBi
|
|||||||
typedef CwiseBinaryOp<internal::scalar_product_op<ScalarBis,Scalar>,
|
typedef CwiseBinaryOp<internal::scalar_product_op<ScalarBis,Scalar>,
|
||||||
const CwiseNullaryOp<internal::scalar_constant_op<ScalarBis>,Plain>,
|
const CwiseNullaryOp<internal::scalar_constant_op<ScalarBis>,Plain>,
|
||||||
const Product<Lhs,Rhs,DefaultProduct> > SrcXprType;
|
const Product<Lhs,Rhs,DefaultProduct> > SrcXprType;
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
static EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
|
||||||
void run(DstXprType &dst, const SrcXprType &src, const AssignFunc& func)
|
void run(DstXprType &dst, const SrcXprType &src, const AssignFunc& func)
|
||||||
{
|
{
|
||||||
call_assignment_no_alias(dst, (src.lhs().functor().m_other * src.rhs().lhs())*src.rhs().rhs(), func);
|
call_assignment_no_alias(dst, (src.lhs().functor().m_other * src.rhs().lhs())*src.rhs().rhs(), func);
|
||||||
@@ -217,7 +217,7 @@ template<typename DstXprType, typename OtherXpr, typename ProductType, typename
|
|||||||
struct assignment_from_xpr_op_product
|
struct assignment_from_xpr_op_product
|
||||||
{
|
{
|
||||||
template<typename SrcXprType, typename InitialFunc>
|
template<typename SrcXprType, typename InitialFunc>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
static EIGEN_STRONG_INLINE
|
||||||
void run(DstXprType &dst, const SrcXprType &src, const InitialFunc& /*func*/)
|
void run(DstXprType &dst, const SrcXprType &src, const InitialFunc& /*func*/)
|
||||||
{
|
{
|
||||||
call_assignment_no_alias(dst, src.lhs(), Func1());
|
call_assignment_no_alias(dst, src.lhs(), Func1());
|
||||||
@@ -246,19 +246,19 @@ template<typename Lhs, typename Rhs>
|
|||||||
struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,InnerProduct>
|
struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,InnerProduct>
|
||||||
{
|
{
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
dst.coeffRef(0,0) = (lhs.transpose().cwiseProduct(rhs)).sum();
|
dst.coeffRef(0,0) = (lhs.transpose().cwiseProduct(rhs)).sum();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
dst.coeffRef(0,0) += (lhs.transpose().cwiseProduct(rhs)).sum();
|
dst.coeffRef(0,0) += (lhs.transpose().cwiseProduct(rhs)).sum();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{ dst.coeffRef(0,0) -= (lhs.transpose().cwiseProduct(rhs)).sum(); }
|
{ dst.coeffRef(0,0) -= (lhs.transpose().cwiseProduct(rhs)).sum(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -269,10 +269,10 @@ struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,InnerProduct>
|
|||||||
|
|
||||||
// Column major result
|
// Column major result
|
||||||
template<typename Dst, typename Lhs, typename Rhs, typename Func>
|
template<typename Dst, typename Lhs, typename Rhs, typename Func>
|
||||||
void EIGEN_DEVICE_FUNC outer_product_selector_run(Dst& dst, const Lhs &lhs, const Rhs &rhs, const Func& func, const false_type&)
|
void outer_product_selector_run(Dst& dst, const Lhs &lhs, const Rhs &rhs, const Func& func, const false_type&)
|
||||||
{
|
{
|
||||||
evaluator<Rhs> rhsEval(rhs);
|
evaluator<Rhs> rhsEval(rhs);
|
||||||
ei_declare_local_nested_eval(Lhs,lhs,Rhs::SizeAtCompileTime,actual_lhs);
|
typename nested_eval<Lhs,Rhs::SizeAtCompileTime>::type actual_lhs(lhs);
|
||||||
// FIXME if cols is large enough, then it might be useful to make sure that lhs is sequentially stored
|
// FIXME if cols is large enough, then it might be useful to make sure that lhs is sequentially stored
|
||||||
// FIXME not very good if rhs is real and lhs complex while alpha is real too
|
// FIXME not very good if rhs is real and lhs complex while alpha is real too
|
||||||
const Index cols = dst.cols();
|
const Index cols = dst.cols();
|
||||||
@@ -282,10 +282,10 @@ void EIGEN_DEVICE_FUNC outer_product_selector_run(Dst& dst, const Lhs &lhs, cons
|
|||||||
|
|
||||||
// Row major result
|
// Row major result
|
||||||
template<typename Dst, typename Lhs, typename Rhs, typename Func>
|
template<typename Dst, typename Lhs, typename Rhs, typename Func>
|
||||||
void EIGEN_DEVICE_FUNC outer_product_selector_run(Dst& dst, const Lhs &lhs, const Rhs &rhs, const Func& func, const true_type&)
|
void outer_product_selector_run(Dst& dst, const Lhs &lhs, const Rhs &rhs, const Func& func, const true_type&)
|
||||||
{
|
{
|
||||||
evaluator<Lhs> lhsEval(lhs);
|
evaluator<Lhs> lhsEval(lhs);
|
||||||
ei_declare_local_nested_eval(Rhs,rhs,Lhs::SizeAtCompileTime,actual_rhs);
|
typename nested_eval<Rhs,Lhs::SizeAtCompileTime>::type actual_rhs(rhs);
|
||||||
// FIXME if rows is large enough, then it might be useful to make sure that rhs is sequentially stored
|
// FIXME if rows is large enough, then it might be useful to make sure that rhs is sequentially stored
|
||||||
// FIXME not very good if lhs is real and rhs complex while alpha is real too
|
// FIXME not very good if lhs is real and rhs complex while alpha is real too
|
||||||
const Index rows = dst.rows();
|
const Index rows = dst.rows();
|
||||||
@@ -300,37 +300,37 @@ struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,OuterProduct>
|
|||||||
typedef typename Product<Lhs,Rhs>::Scalar Scalar;
|
typedef typename Product<Lhs,Rhs>::Scalar Scalar;
|
||||||
|
|
||||||
// TODO it would be nice to be able to exploit our *_assign_op functors for that purpose
|
// TODO it would be nice to be able to exploit our *_assign_op functors for that purpose
|
||||||
struct set { template<typename Dst, typename Src> EIGEN_DEVICE_FUNC void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() = src; } };
|
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> EIGEN_DEVICE_FUNC 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> EIGEN_DEVICE_FUNC 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 {
|
struct adds {
|
||||||
Scalar m_scale;
|
Scalar m_scale;
|
||||||
explicit adds(const Scalar& s) : m_scale(s) {}
|
explicit adds(const Scalar& s) : m_scale(s) {}
|
||||||
template<typename Dst, typename Src> void EIGEN_DEVICE_FUNC operator()(const Dst& dst, const Src& src) const {
|
template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const {
|
||||||
dst.const_cast_derived() += m_scale * src;
|
dst.const_cast_derived() += m_scale * src;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
internal::outer_product_selector_run(dst, lhs, rhs, set(), is_row_major<Dst>());
|
internal::outer_product_selector_run(dst, lhs, rhs, set(), is_row_major<Dst>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
internal::outer_product_selector_run(dst, lhs, rhs, add(), is_row_major<Dst>());
|
internal::outer_product_selector_run(dst, lhs, rhs, add(), is_row_major<Dst>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
internal::outer_product_selector_run(dst, lhs, rhs, sub(), is_row_major<Dst>());
|
internal::outer_product_selector_run(dst, lhs, rhs, sub(), is_row_major<Dst>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
static EIGEN_STRONG_INLINE void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
||||||
{
|
{
|
||||||
internal::outer_product_selector_run(dst, lhs, rhs, adds(alpha), is_row_major<Dst>());
|
internal::outer_product_selector_run(dst, lhs, rhs, adds(alpha), is_row_major<Dst>());
|
||||||
}
|
}
|
||||||
@@ -345,19 +345,19 @@ struct generic_product_impl_base
|
|||||||
typedef typename Product<Lhs,Rhs>::Scalar Scalar;
|
typedef typename Product<Lhs,Rhs>::Scalar Scalar;
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{ dst.setZero(); scaleAndAddTo(dst, lhs, rhs, Scalar(1)); }
|
{ dst.setZero(); scaleAndAddTo(dst, lhs, rhs, Scalar(1)); }
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{ scaleAndAddTo(dst,lhs, rhs, Scalar(1)); }
|
{ scaleAndAddTo(dst,lhs, rhs, Scalar(1)); }
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{ scaleAndAddTo(dst, lhs, rhs, Scalar(-1)); }
|
{ scaleAndAddTo(dst, lhs, rhs, Scalar(-1)); }
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
static EIGEN_STRONG_INLINE void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
||||||
{ Derived::scaleAndAddTo(dst,lhs,rhs,alpha); }
|
{ Derived::scaleAndAddTo(dst,lhs,rhs,alpha); }
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -373,13 +373,8 @@ struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,GemvProduct>
|
|||||||
typedef typename internal::remove_all<typename internal::conditional<int(Side)==OnTheRight,LhsNested,RhsNested>::type>::type MatrixType;
|
typedef typename internal::remove_all<typename internal::conditional<int(Side)==OnTheRight,LhsNested,RhsNested>::type>::type MatrixType;
|
||||||
|
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
static EIGEN_STRONG_INLINE void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
||||||
{
|
{
|
||||||
// Fallback to inner product if both the lhs and rhs is a runtime vector.
|
|
||||||
if (lhs.rows() == 1 && rhs.cols() == 1) {
|
|
||||||
dst.coeffRef(0,0) += alpha * lhs.row(0).conjugate().dot(rhs.col(0));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LhsNested actual_lhs(lhs);
|
LhsNested actual_lhs(lhs);
|
||||||
RhsNested actual_rhs(rhs);
|
RhsNested actual_rhs(rhs);
|
||||||
internal::gemv_dense_selector<Side,
|
internal::gemv_dense_selector<Side,
|
||||||
@@ -403,71 +398,48 @@ struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,CoeffBasedProductMode>
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
// dst.noalias() += lhs.lazyProduct(rhs);
|
// dst.noalias() += lhs.lazyProduct(rhs);
|
||||||
call_assignment_no_alias(dst, lhs.lazyProduct(rhs), internal::add_assign_op<typename Dst::Scalar,Scalar>());
|
call_assignment_no_alias(dst, lhs.lazyProduct(rhs), internal::add_assign_op<typename Dst::Scalar,Scalar>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
// dst.noalias() -= lhs.lazyProduct(rhs);
|
// dst.noalias() -= lhs.lazyProduct(rhs);
|
||||||
call_assignment_no_alias(dst, lhs.lazyProduct(rhs), internal::sub_assign_op<typename Dst::Scalar,Scalar>());
|
call_assignment_no_alias(dst, lhs.lazyProduct(rhs), internal::sub_assign_op<typename Dst::Scalar,Scalar>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a special evaluation path called from generic_product_impl<...,GemmProduct> in file GeneralMatrixMatrix.h
|
// Catch "dst {,+,-}= (s*A)*B" and evaluate it lazily by moving out the scalar factor:
|
||||||
// This variant tries to extract scalar multiples from both the LHS and RHS and factor them out. For instance:
|
// dst {,+,-}= s * (A.lazyProduct(B))
|
||||||
// dst {,+,-}= (s1*A)*(B*s2)
|
// This is a huge benefit for heap-allocated matrix types as it save one costly allocation.
|
||||||
// will be rewritten as:
|
// For them, this strategy is also faster than simply by-passing the heap allocation through
|
||||||
// dst {,+,-}= (s1*s2) * (A.lazyProduct(B))
|
// stack allocation.
|
||||||
// There are at least four benefits of doing so:
|
// For fixed sizes matrices, this is less obvious, it is sometimes x2 faster, but sometimes x3 slower,
|
||||||
// 1 - huge performance gain for heap-allocated matrix types as it save costly allocations.
|
// and the behavior depends also a lot on the compiler... so let's be conservative and enable them for dynamic-size only,
|
||||||
// 2 - it is faster than simply by-passing the heap allocation through stack allocation.
|
// that is when coming from generic_product_impl<...,GemmProduct> in file GeneralMatrixMatrix.h
|
||||||
// 3 - it makes this fallback consistent with the heavy GEMM routine.
|
template<typename Dst, typename Scalar1, typename Scalar2, typename Plain1, typename Xpr2, typename Func>
|
||||||
// 4 - it fully by-passes huge stack allocation attempts when multiplying huge fixed-size matrices.
|
|
||||||
// (see https://stackoverflow.com/questions/54738495)
|
|
||||||
// For small fixed sizes matrices, howver, the gains are less obvious, it is sometimes x2 faster, but sometimes x3 slower,
|
|
||||||
// and the behavior depends also a lot on the compiler... This is why this re-writting strategy is currently
|
|
||||||
// enabled only when falling back from the main GEMM.
|
|
||||||
template<typename Dst, typename Func>
|
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
void eval_dynamic(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Func &func)
|
void eval_dynamic(Dst& dst, const CwiseBinaryOp<internal::scalar_product_op<Scalar1,Scalar2>,
|
||||||
|
const CwiseNullaryOp<internal::scalar_constant_op<Scalar1>, Plain1>, Xpr2>& lhs, const Rhs& rhs, const Func &func)
|
||||||
{
|
{
|
||||||
enum {
|
call_assignment_no_alias(dst, lhs.lhs().functor().m_other * lhs.rhs().lazyProduct(rhs), func);
|
||||||
HasScalarFactor = blas_traits<Lhs>::HasScalarFactor || blas_traits<Rhs>::HasScalarFactor,
|
|
||||||
ConjLhs = blas_traits<Lhs>::NeedToConjugate,
|
|
||||||
ConjRhs = blas_traits<Rhs>::NeedToConjugate
|
|
||||||
};
|
|
||||||
// FIXME: in c++11 this should be auto, and extractScalarFactor should also return auto
|
|
||||||
// this is important for real*complex_mat
|
|
||||||
Scalar actualAlpha = combine_scalar_factors<Scalar>(lhs, rhs);
|
|
||||||
|
|
||||||
eval_dynamic_impl(dst,
|
|
||||||
blas_traits<Lhs>::extract(lhs).template conjugateIf<ConjLhs>(),
|
|
||||||
blas_traits<Rhs>::extract(rhs).template conjugateIf<ConjRhs>(),
|
|
||||||
func,
|
|
||||||
actualAlpha,
|
|
||||||
typename conditional<HasScalarFactor,true_type,false_type>::type());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
// Here, we we always have LhsT==Lhs, but we need to make it a template type to make the above
|
||||||
|
// overload more specialized.
|
||||||
template<typename Dst, typename LhsT, typename RhsT, typename Func, typename Scalar>
|
template<typename Dst, typename LhsT, typename Func>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
void eval_dynamic_impl(Dst& dst, const LhsT& lhs, const RhsT& rhs, const Func &func, const Scalar& s /* == 1 */, false_type)
|
void eval_dynamic(Dst& dst, const LhsT& lhs, const Rhs& rhs, const Func &func)
|
||||||
{
|
{
|
||||||
EIGEN_UNUSED_VARIABLE(s);
|
call_assignment_no_alias(dst, lhs.lazyProduct(rhs), func);
|
||||||
eigen_internal_assert(s==Scalar(1));
|
|
||||||
call_restricted_packet_assignment_no_alias(dst, lhs.lazyProduct(rhs), func);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Dst, typename LhsT, typename RhsT, typename Func, typename Scalar>
|
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
// template<typename Dst>
|
||||||
void eval_dynamic_impl(Dst& dst, const LhsT& lhs, const RhsT& rhs, const Func &func, const Scalar& s, true_type)
|
// static inline void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
||||||
{
|
// { dst.noalias() += alpha * lhs.lazyProduct(rhs); }
|
||||||
call_restricted_packet_assignment_no_alias(dst, s * lhs.lazyProduct(rhs), func);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// This specialization enforces the use of a coefficient-based evaluation strategy
|
// This specialization enforces the use of a coefficient-based evaluation strategy
|
||||||
@@ -549,7 +521,7 @@ struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape,
|
|||||||
RhsCoeffReadCost = RhsEtorType::CoeffReadCost,
|
RhsCoeffReadCost = RhsEtorType::CoeffReadCost,
|
||||||
CoeffReadCost = InnerSize==0 ? NumTraits<Scalar>::ReadCost
|
CoeffReadCost = InnerSize==0 ? NumTraits<Scalar>::ReadCost
|
||||||
: InnerSize == Dynamic ? HugeCost
|
: InnerSize == Dynamic ? HugeCost
|
||||||
: InnerSize * (NumTraits<Scalar>::MulCost + int(LhsCoeffReadCost) + int(RhsCoeffReadCost))
|
: InnerSize * (NumTraits<Scalar>::MulCost + LhsCoeffReadCost + RhsCoeffReadCost)
|
||||||
+ (InnerSize - 1) * NumTraits<Scalar>::AddCost,
|
+ (InnerSize - 1) * NumTraits<Scalar>::AddCost,
|
||||||
|
|
||||||
Unroll = CoeffReadCost <= EIGEN_UNROLLING_LIMIT,
|
Unroll = CoeffReadCost <= EIGEN_UNROLLING_LIMIT,
|
||||||
@@ -576,7 +548,7 @@ struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape,
|
|||||||
: (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
|
: (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
|
||||||
: (bool(RhsRowMajor) && !CanVectorizeLhs),
|
: (bool(RhsRowMajor) && !CanVectorizeLhs),
|
||||||
|
|
||||||
Flags = ((int(LhsFlags) | int(RhsFlags)) & HereditaryBits & ~RowMajorBit)
|
Flags = ((unsigned int)(LhsFlags | RhsFlags) & HereditaryBits & ~RowMajorBit)
|
||||||
| (EvalToRowMajor ? RowMajorBit : 0)
|
| (EvalToRowMajor ? RowMajorBit : 0)
|
||||||
// TODO enable vectorization for mixed types
|
// TODO enable vectorization for mixed types
|
||||||
| (SameType && (CanVectorizeLhs || CanVectorizeRhs) ? PacketAccessBit : 0)
|
| (SameType && (CanVectorizeLhs || CanVectorizeRhs) ? PacketAccessBit : 0)
|
||||||
@@ -597,8 +569,8 @@ struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape,
|
|||||||
CanVectorizeInner = SameType
|
CanVectorizeInner = SameType
|
||||||
&& LhsRowMajor
|
&& LhsRowMajor
|
||||||
&& (!RhsRowMajor)
|
&& (!RhsRowMajor)
|
||||||
&& (int(LhsFlags) & int(RhsFlags) & ActualPacketAccessBit)
|
&& (LhsFlags & RhsFlags & ActualPacketAccessBit)
|
||||||
&& (int(InnerSize) % packet_traits<Scalar>::size == 0)
|
&& (InnerSize % packet_traits<Scalar>::size == 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index row, Index col) const
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index row, Index col) const
|
||||||
@@ -610,8 +582,7 @@ struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape,
|
|||||||
* which is why we don't set the LinearAccessBit.
|
* which is why we don't set the LinearAccessBit.
|
||||||
* TODO: this seems possible when the result is a vector
|
* TODO: this seems possible when the result is a vector
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC const CoeffReturnType coeff(Index index) const
|
||||||
const CoeffReturnType coeff(Index index) const
|
|
||||||
{
|
{
|
||||||
const Index row = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? 0 : index;
|
const Index row = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? 0 : index;
|
||||||
const Index col = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? index : 0;
|
const Index col = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? index : 0;
|
||||||
@@ -619,7 +590,6 @@ struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
template<int LoadMode, typename PacketType>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
const PacketType packet(Index row, Index col) const
|
const PacketType packet(Index row, Index col) const
|
||||||
{
|
{
|
||||||
PacketType res;
|
PacketType res;
|
||||||
@@ -631,7 +601,6 @@ struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
template<int LoadMode, typename PacketType>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
const PacketType packet(Index index) const
|
const PacketType packet(Index index) const
|
||||||
{
|
{
|
||||||
const Index row = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? 0 : index;
|
const Index row = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? 0 : index;
|
||||||
@@ -660,8 +629,7 @@ struct product_evaluator<Product<Lhs, Rhs, DefaultProduct>, LazyCoeffBasedProduc
|
|||||||
enum {
|
enum {
|
||||||
Flags = Base::Flags | EvalBeforeNestingBit
|
Flags = Base::Flags | EvalBeforeNestingBit
|
||||||
};
|
};
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr)
|
||||||
explicit product_evaluator(const XprType& xpr)
|
|
||||||
: Base(BaseProduct(xpr.lhs(),xpr.rhs()))
|
: Base(BaseProduct(xpr.lhs(),xpr.rhs()))
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
@@ -673,7 +641,7 @@ struct product_evaluator<Product<Lhs, Rhs, DefaultProduct>, LazyCoeffBasedProduc
|
|||||||
template<int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
template<int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||||
struct etor_product_packet_impl<RowMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode>
|
struct etor_product_packet_impl<RowMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode>
|
||||||
{
|
{
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet &res)
|
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet &res)
|
||||||
{
|
{
|
||||||
etor_product_packet_impl<RowMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, innerDim, res);
|
etor_product_packet_impl<RowMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, innerDim, res);
|
||||||
res = pmadd(pset1<Packet>(lhs.coeff(row, Index(UnrollingIndex-1))), rhs.template packet<LoadMode,Packet>(Index(UnrollingIndex-1), col), res);
|
res = pmadd(pset1<Packet>(lhs.coeff(row, Index(UnrollingIndex-1))), rhs.template packet<LoadMode,Packet>(Index(UnrollingIndex-1), col), res);
|
||||||
@@ -683,7 +651,7 @@ struct etor_product_packet_impl<RowMajor, UnrollingIndex, Lhs, Rhs, Packet, Load
|
|||||||
template<int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
template<int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||||
struct etor_product_packet_impl<ColMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode>
|
struct etor_product_packet_impl<ColMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode>
|
||||||
{
|
{
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet &res)
|
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet &res)
|
||||||
{
|
{
|
||||||
etor_product_packet_impl<ColMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, innerDim, res);
|
etor_product_packet_impl<ColMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, innerDim, res);
|
||||||
res = pmadd(lhs.template packet<LoadMode,Packet>(row, Index(UnrollingIndex-1)), pset1<Packet>(rhs.coeff(Index(UnrollingIndex-1), col)), res);
|
res = pmadd(lhs.template packet<LoadMode,Packet>(row, Index(UnrollingIndex-1)), pset1<Packet>(rhs.coeff(Index(UnrollingIndex-1), col)), res);
|
||||||
@@ -693,7 +661,7 @@ struct etor_product_packet_impl<ColMajor, UnrollingIndex, Lhs, Rhs, Packet, Load
|
|||||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||||
struct etor_product_packet_impl<RowMajor, 1, Lhs, Rhs, Packet, LoadMode>
|
struct etor_product_packet_impl<RowMajor, 1, Lhs, Rhs, Packet, LoadMode>
|
||||||
{
|
{
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index /*innerDim*/, Packet &res)
|
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index /*innerDim*/, Packet &res)
|
||||||
{
|
{
|
||||||
res = pmul(pset1<Packet>(lhs.coeff(row, Index(0))),rhs.template packet<LoadMode,Packet>(Index(0), col));
|
res = pmul(pset1<Packet>(lhs.coeff(row, Index(0))),rhs.template packet<LoadMode,Packet>(Index(0), col));
|
||||||
}
|
}
|
||||||
@@ -702,7 +670,7 @@ struct etor_product_packet_impl<RowMajor, 1, Lhs, Rhs, Packet, LoadMode>
|
|||||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||||
struct etor_product_packet_impl<ColMajor, 1, Lhs, Rhs, Packet, LoadMode>
|
struct etor_product_packet_impl<ColMajor, 1, Lhs, Rhs, Packet, LoadMode>
|
||||||
{
|
{
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index /*innerDim*/, Packet &res)
|
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index /*innerDim*/, Packet &res)
|
||||||
{
|
{
|
||||||
res = pmul(lhs.template packet<LoadMode,Packet>(row, Index(0)), pset1<Packet>(rhs.coeff(Index(0), col)));
|
res = pmul(lhs.template packet<LoadMode,Packet>(row, Index(0)), pset1<Packet>(rhs.coeff(Index(0), col)));
|
||||||
}
|
}
|
||||||
@@ -711,7 +679,7 @@ struct etor_product_packet_impl<ColMajor, 1, Lhs, Rhs, Packet, LoadMode>
|
|||||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||||
struct etor_product_packet_impl<RowMajor, 0, Lhs, Rhs, Packet, LoadMode>
|
struct etor_product_packet_impl<RowMajor, 0, Lhs, Rhs, Packet, LoadMode>
|
||||||
{
|
{
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, Index /*innerDim*/, Packet &res)
|
static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, Index /*innerDim*/, Packet &res)
|
||||||
{
|
{
|
||||||
res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
|
res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
|
||||||
}
|
}
|
||||||
@@ -720,7 +688,7 @@ struct etor_product_packet_impl<RowMajor, 0, Lhs, Rhs, Packet, LoadMode>
|
|||||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||||
struct etor_product_packet_impl<ColMajor, 0, Lhs, Rhs, Packet, LoadMode>
|
struct etor_product_packet_impl<ColMajor, 0, Lhs, Rhs, Packet, LoadMode>
|
||||||
{
|
{
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, Index /*innerDim*/, Packet &res)
|
static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, Index /*innerDim*/, Packet &res)
|
||||||
{
|
{
|
||||||
res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
|
res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
|
||||||
}
|
}
|
||||||
@@ -729,7 +697,7 @@ struct etor_product_packet_impl<ColMajor, 0, Lhs, Rhs, Packet, LoadMode>
|
|||||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||||
struct etor_product_packet_impl<RowMajor, Dynamic, Lhs, Rhs, Packet, LoadMode>
|
struct etor_product_packet_impl<RowMajor, Dynamic, Lhs, Rhs, Packet, LoadMode>
|
||||||
{
|
{
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet& res)
|
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet& res)
|
||||||
{
|
{
|
||||||
res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
|
res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
|
||||||
for(Index i = 0; i < innerDim; ++i)
|
for(Index i = 0; i < innerDim; ++i)
|
||||||
@@ -740,7 +708,7 @@ struct etor_product_packet_impl<RowMajor, Dynamic, Lhs, Rhs, Packet, LoadMode>
|
|||||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||||
struct etor_product_packet_impl<ColMajor, Dynamic, Lhs, Rhs, Packet, LoadMode>
|
struct etor_product_packet_impl<ColMajor, Dynamic, Lhs, Rhs, Packet, LoadMode>
|
||||||
{
|
{
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet& res)
|
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet& res)
|
||||||
{
|
{
|
||||||
res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
|
res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
|
||||||
for(Index i = 0; i < innerDim; ++i)
|
for(Index i = 0; i < innerDim; ++i)
|
||||||
@@ -799,8 +767,7 @@ struct generic_product_impl<Lhs,Rhs,SelfAdjointShape,DenseShape,ProductTag>
|
|||||||
typedef typename Product<Lhs,Rhs>::Scalar Scalar;
|
typedef typename Product<Lhs,Rhs>::Scalar Scalar;
|
||||||
|
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
static EIGEN_DEVICE_FUNC
|
static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
||||||
void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
|
||||||
{
|
{
|
||||||
selfadjoint_product_impl<typename Lhs::MatrixType,Lhs::Mode,false,Rhs,0,Rhs::IsVectorAtCompileTime>::run(dst, lhs.nestedExpression(), rhs, alpha);
|
selfadjoint_product_impl<typename Lhs::MatrixType,Lhs::Mode,false,Rhs,0,Rhs::IsVectorAtCompileTime>::run(dst, lhs.nestedExpression(), rhs, alpha);
|
||||||
}
|
}
|
||||||
@@ -831,25 +798,17 @@ struct diagonal_product_evaluator_base
|
|||||||
typedef typename ScalarBinaryOpTraits<typename MatrixType::Scalar, typename DiagonalType::Scalar>::ReturnType Scalar;
|
typedef typename ScalarBinaryOpTraits<typename MatrixType::Scalar, typename DiagonalType::Scalar>::ReturnType Scalar;
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
CoeffReadCost = int(NumTraits<Scalar>::MulCost) + int(evaluator<MatrixType>::CoeffReadCost) + int(evaluator<DiagonalType>::CoeffReadCost),
|
CoeffReadCost = NumTraits<Scalar>::MulCost + evaluator<MatrixType>::CoeffReadCost + evaluator<DiagonalType>::CoeffReadCost,
|
||||||
|
|
||||||
MatrixFlags = evaluator<MatrixType>::Flags,
|
MatrixFlags = evaluator<MatrixType>::Flags,
|
||||||
DiagFlags = evaluator<DiagonalType>::Flags,
|
DiagFlags = evaluator<DiagonalType>::Flags,
|
||||||
|
_StorageOrder = MatrixFlags & RowMajorBit ? RowMajor : ColMajor,
|
||||||
_StorageOrder = (Derived::MaxRowsAtCompileTime==1 && Derived::MaxColsAtCompileTime!=1) ? RowMajor
|
|
||||||
: (Derived::MaxColsAtCompileTime==1 && Derived::MaxRowsAtCompileTime!=1) ? ColMajor
|
|
||||||
: MatrixFlags & RowMajorBit ? RowMajor : ColMajor,
|
|
||||||
_SameStorageOrder = _StorageOrder == (MatrixFlags & RowMajorBit ? RowMajor : ColMajor),
|
|
||||||
|
|
||||||
_ScalarAccessOnDiag = !((int(_StorageOrder) == ColMajor && int(ProductOrder) == OnTheLeft)
|
_ScalarAccessOnDiag = !((int(_StorageOrder) == ColMajor && int(ProductOrder) == OnTheLeft)
|
||||||
||(int(_StorageOrder) == RowMajor && int(ProductOrder) == OnTheRight)),
|
||(int(_StorageOrder) == RowMajor && int(ProductOrder) == OnTheRight)),
|
||||||
_SameTypes = is_same<typename MatrixType::Scalar, typename DiagonalType::Scalar>::value,
|
_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
|
// FIXME currently we need same types, but in the future the next rule should be the one
|
||||||
//_Vectorizable = bool(int(MatrixFlags)&PacketAccessBit) && ((!_PacketOnDiag) || (_SameTypes && bool(int(DiagFlags)&PacketAccessBit))),
|
//_Vectorizable = bool(int(MatrixFlags)&PacketAccessBit) && ((!_PacketOnDiag) || (_SameTypes && bool(int(DiagFlags)&PacketAccessBit))),
|
||||||
_Vectorizable = bool(int(MatrixFlags)&PacketAccessBit)
|
_Vectorizable = bool(int(MatrixFlags)&PacketAccessBit) && _SameTypes && (_ScalarAccessOnDiag || (bool(int(DiagFlags)&PacketAccessBit))),
|
||||||
&& _SameTypes
|
|
||||||
&& (_SameStorageOrder || (MatrixFlags&LinearAccessBit)==LinearAccessBit)
|
|
||||||
&& (_ScalarAccessOnDiag || (bool(int(DiagFlags)&PacketAccessBit))),
|
|
||||||
_LinearAccessMask = (MatrixType::RowsAtCompileTime==1 || MatrixType::ColsAtCompileTime==1) ? LinearAccessBit : 0,
|
_LinearAccessMask = (MatrixType::RowsAtCompileTime==1 || MatrixType::ColsAtCompileTime==1) ? LinearAccessBit : 0,
|
||||||
Flags = ((HereditaryBits|_LinearAccessMask) & (unsigned int)(MatrixFlags)) | (_Vectorizable ? PacketAccessBit : 0),
|
Flags = ((HereditaryBits|_LinearAccessMask) & (unsigned int)(MatrixFlags)) | (_Vectorizable ? PacketAccessBit : 0),
|
||||||
Alignment = evaluator<MatrixType>::Alignment,
|
Alignment = evaluator<MatrixType>::Alignment,
|
||||||
@@ -859,7 +818,7 @@ public:
|
|||||||
|| (DiagonalType::SizeAtCompileTime==Dynamic && MatrixType::ColsAtCompileTime==1 && ProductOrder==OnTheRight)
|
|| (DiagonalType::SizeAtCompileTime==Dynamic && MatrixType::ColsAtCompileTime==1 && ProductOrder==OnTheRight)
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC diagonal_product_evaluator_base(const MatrixType &mat, const DiagonalType &diag)
|
diagonal_product_evaluator_base(const MatrixType &mat, const DiagonalType &diag)
|
||||||
: m_diagImpl(diag), m_matImpl(mat)
|
: m_diagImpl(diag), m_matImpl(mat)
|
||||||
{
|
{
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(NumTraits<Scalar>::MulCost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(NumTraits<Scalar>::MulCost);
|
||||||
@@ -910,10 +869,10 @@ struct product_evaluator<Product<Lhs, Rhs, ProductKind>, ProductTag, DiagonalSha
|
|||||||
|
|
||||||
typedef Product<Lhs, Rhs, ProductKind> XprType;
|
typedef Product<Lhs, Rhs, ProductKind> XprType;
|
||||||
typedef typename XprType::PlainObject PlainObject;
|
typedef typename XprType::PlainObject PlainObject;
|
||||||
typedef typename Lhs::DiagonalVectorType DiagonalType;
|
|
||||||
|
|
||||||
|
enum {
|
||||||
enum { StorageOrder = Base::_StorageOrder };
|
StorageOrder = int(Rhs::Flags) & RowMajorBit ? RowMajor : ColMajor
|
||||||
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr)
|
EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr)
|
||||||
: Base(xpr.rhs(), xpr.lhs().diagonal())
|
: Base(xpr.rhs(), xpr.lhs().diagonal())
|
||||||
@@ -925,7 +884,7 @@ struct product_evaluator<Product<Lhs, Rhs, ProductKind>, ProductTag, DiagonalSha
|
|||||||
return m_diagImpl.coeff(row) * m_matImpl.coeff(row, col);
|
return m_diagImpl.coeff(row) * m_matImpl.coeff(row, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_GPUCC
|
#ifndef __CUDACC__
|
||||||
template<int LoadMode,typename PacketType>
|
template<int LoadMode,typename PacketType>
|
||||||
EIGEN_STRONG_INLINE PacketType packet(Index row, Index col) const
|
EIGEN_STRONG_INLINE PacketType packet(Index row, Index col) const
|
||||||
{
|
{
|
||||||
@@ -957,7 +916,7 @@ struct product_evaluator<Product<Lhs, Rhs, ProductKind>, ProductTag, DenseShape,
|
|||||||
typedef Product<Lhs, Rhs, ProductKind> XprType;
|
typedef Product<Lhs, Rhs, ProductKind> XprType;
|
||||||
typedef typename XprType::PlainObject PlainObject;
|
typedef typename XprType::PlainObject PlainObject;
|
||||||
|
|
||||||
enum { StorageOrder = Base::_StorageOrder };
|
enum { StorageOrder = int(Lhs::Flags) & RowMajorBit ? RowMajor : ColMajor };
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr)
|
EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr)
|
||||||
: Base(xpr.lhs(), xpr.rhs().diagonal())
|
: Base(xpr.lhs(), xpr.rhs().diagonal())
|
||||||
@@ -969,7 +928,7 @@ struct product_evaluator<Product<Lhs, Rhs, ProductKind>, ProductTag, DenseShape,
|
|||||||
return m_matImpl.coeff(row, col) * m_diagImpl.coeff(col);
|
return m_matImpl.coeff(row, col) * m_diagImpl.coeff(col);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_GPUCC
|
#ifndef __CUDACC__
|
||||||
template<int LoadMode,typename PacketType>
|
template<int LoadMode,typename PacketType>
|
||||||
EIGEN_STRONG_INLINE PacketType packet(Index row, Index col) const
|
EIGEN_STRONG_INLINE PacketType packet(Index row, Index col) const
|
||||||
{
|
{
|
||||||
@@ -1004,7 +963,7 @@ struct permutation_matrix_product<ExpressionType, Side, Transposed, DenseShape>
|
|||||||
typedef typename remove_all<MatrixType>::type MatrixTypeCleaned;
|
typedef typename remove_all<MatrixType>::type MatrixTypeCleaned;
|
||||||
|
|
||||||
template<typename Dest, typename PermutationType>
|
template<typename Dest, typename PermutationType>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Dest& dst, const PermutationType& perm, const ExpressionType& xpr)
|
static inline void run(Dest& dst, const PermutationType& perm, const ExpressionType& xpr)
|
||||||
{
|
{
|
||||||
MatrixType mat(xpr);
|
MatrixType mat(xpr);
|
||||||
const Index n = Side==OnTheLeft ? mat.rows() : mat.cols();
|
const Index n = Side==OnTheLeft ? mat.rows() : mat.cols();
|
||||||
@@ -1058,7 +1017,7 @@ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
|
|||||||
struct generic_product_impl<Lhs, Rhs, PermutationShape, MatrixShape, ProductTag>
|
struct generic_product_impl<Lhs, Rhs, PermutationShape, MatrixShape, ProductTag>
|
||||||
{
|
{
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
permutation_matrix_product<Rhs, OnTheLeft, false, MatrixShape>::run(dst, lhs, rhs);
|
permutation_matrix_product<Rhs, OnTheLeft, false, MatrixShape>::run(dst, lhs, rhs);
|
||||||
}
|
}
|
||||||
@@ -1068,7 +1027,7 @@ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
|
|||||||
struct generic_product_impl<Lhs, Rhs, MatrixShape, PermutationShape, ProductTag>
|
struct generic_product_impl<Lhs, Rhs, MatrixShape, PermutationShape, ProductTag>
|
||||||
{
|
{
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
permutation_matrix_product<Lhs, OnTheRight, false, MatrixShape>::run(dst, rhs, lhs);
|
permutation_matrix_product<Lhs, OnTheRight, false, MatrixShape>::run(dst, rhs, lhs);
|
||||||
}
|
}
|
||||||
@@ -1078,7 +1037,7 @@ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
|
|||||||
struct generic_product_impl<Inverse<Lhs>, Rhs, PermutationShape, MatrixShape, ProductTag>
|
struct generic_product_impl<Inverse<Lhs>, Rhs, PermutationShape, MatrixShape, ProductTag>
|
||||||
{
|
{
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Inverse<Lhs>& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC void evalTo(Dest& dst, const Inverse<Lhs>& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
permutation_matrix_product<Rhs, OnTheLeft, true, MatrixShape>::run(dst, lhs.nestedExpression(), rhs);
|
permutation_matrix_product<Rhs, OnTheLeft, true, MatrixShape>::run(dst, lhs.nestedExpression(), rhs);
|
||||||
}
|
}
|
||||||
@@ -1088,7 +1047,7 @@ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
|
|||||||
struct generic_product_impl<Lhs, Inverse<Rhs>, MatrixShape, PermutationShape, ProductTag>
|
struct generic_product_impl<Lhs, Inverse<Rhs>, MatrixShape, PermutationShape, ProductTag>
|
||||||
{
|
{
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Inverse<Rhs>& rhs)
|
static EIGEN_DEVICE_FUNC void evalTo(Dest& dst, const Lhs& lhs, const Inverse<Rhs>& rhs)
|
||||||
{
|
{
|
||||||
permutation_matrix_product<Lhs, OnTheRight, true, MatrixShape>::run(dst, rhs.nestedExpression(), lhs);
|
permutation_matrix_product<Lhs, OnTheRight, true, MatrixShape>::run(dst, rhs.nestedExpression(), lhs);
|
||||||
}
|
}
|
||||||
@@ -1112,7 +1071,7 @@ struct transposition_matrix_product
|
|||||||
typedef typename remove_all<MatrixType>::type MatrixTypeCleaned;
|
typedef typename remove_all<MatrixType>::type MatrixTypeCleaned;
|
||||||
|
|
||||||
template<typename Dest, typename TranspositionType>
|
template<typename Dest, typename TranspositionType>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Dest& dst, const TranspositionType& tr, const ExpressionType& xpr)
|
static inline void run(Dest& dst, const TranspositionType& tr, const ExpressionType& xpr)
|
||||||
{
|
{
|
||||||
MatrixType mat(xpr);
|
MatrixType mat(xpr);
|
||||||
typedef typename TranspositionType::StorageIndex StorageIndex;
|
typedef typename TranspositionType::StorageIndex StorageIndex;
|
||||||
@@ -1135,7 +1094,7 @@ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
|
|||||||
struct generic_product_impl<Lhs, Rhs, TranspositionsShape, MatrixShape, ProductTag>
|
struct generic_product_impl<Lhs, Rhs, TranspositionsShape, MatrixShape, ProductTag>
|
||||||
{
|
{
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
transposition_matrix_product<Rhs, OnTheLeft, false, MatrixShape>::run(dst, lhs, rhs);
|
transposition_matrix_product<Rhs, OnTheLeft, false, MatrixShape>::run(dst, lhs, rhs);
|
||||||
}
|
}
|
||||||
@@ -1145,7 +1104,7 @@ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
|
|||||||
struct generic_product_impl<Lhs, Rhs, MatrixShape, TranspositionsShape, ProductTag>
|
struct generic_product_impl<Lhs, Rhs, MatrixShape, TranspositionsShape, ProductTag>
|
||||||
{
|
{
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
transposition_matrix_product<Lhs, OnTheRight, false, MatrixShape>::run(dst, rhs, lhs);
|
transposition_matrix_product<Lhs, OnTheRight, false, MatrixShape>::run(dst, rhs, lhs);
|
||||||
}
|
}
|
||||||
@@ -1156,7 +1115,7 @@ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
|
|||||||
struct generic_product_impl<Transpose<Lhs>, Rhs, TranspositionsShape, MatrixShape, ProductTag>
|
struct generic_product_impl<Transpose<Lhs>, Rhs, TranspositionsShape, MatrixShape, ProductTag>
|
||||||
{
|
{
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Transpose<Lhs>& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC void evalTo(Dest& dst, const Transpose<Lhs>& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
transposition_matrix_product<Rhs, OnTheLeft, true, MatrixShape>::run(dst, lhs.nestedExpression(), rhs);
|
transposition_matrix_product<Rhs, OnTheLeft, true, MatrixShape>::run(dst, lhs.nestedExpression(), rhs);
|
||||||
}
|
}
|
||||||
@@ -1166,7 +1125,7 @@ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
|
|||||||
struct generic_product_impl<Lhs, Transpose<Rhs>, MatrixShape, TranspositionsShape, ProductTag>
|
struct generic_product_impl<Lhs, Transpose<Rhs>, MatrixShape, TranspositionsShape, ProductTag>
|
||||||
{
|
{
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Transpose<Rhs>& rhs)
|
static EIGEN_DEVICE_FUNC void evalTo(Dest& dst, const Lhs& lhs, const Transpose<Rhs>& rhs)
|
||||||
{
|
{
|
||||||
transposition_matrix_product<Lhs, OnTheRight, true, MatrixShape>::run(dst, rhs.nestedExpression(), lhs);
|
transposition_matrix_product<Lhs, OnTheRight, true, MatrixShape>::run(dst, rhs.nestedExpression(), lhs);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -177,42 +177,6 @@ PlainObjectBase<Derived>::setRandom(Index rows, Index cols)
|
|||||||
return setRandom();
|
return setRandom();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Resizes to the given size, changing only the number of columns, and sets all
|
|
||||||
* coefficients in this expression to random values. For the parameter of type
|
|
||||||
* NoChange_t, just pass the special value \c NoChange.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* \sa DenseBase::setRandom(), setRandom(Index), setRandom(Index, NoChange_t), class CwiseNullaryOp, DenseBase::Random()
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
EIGEN_STRONG_INLINE Derived&
|
|
||||||
PlainObjectBase<Derived>::setRandom(NoChange_t, Index cols)
|
|
||||||
{
|
|
||||||
return setRandom(rows(), cols);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Resizes to the given size, changing only the number of rows, and sets all
|
|
||||||
* coefficients in this expression to random values. For the parameter of type
|
|
||||||
* NoChange_t, just pass the special value \c NoChange.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* \sa DenseBase::setRandom(), setRandom(Index), setRandom(NoChange_t, Index), class CwiseNullaryOp, DenseBase::Random()
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
EIGEN_STRONG_INLINE Derived&
|
|
||||||
PlainObjectBase<Derived>::setRandom(Index rows, NoChange_t)
|
|
||||||
{
|
|
||||||
return setRandom(rows, cols());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_RANDOM_H
|
#endif // EIGEN_RANDOM_H
|
||||||
|
|||||||
@@ -23,29 +23,23 @@ namespace internal {
|
|||||||
* Part 1 : the logic deciding a strategy for vectorization and unrolling
|
* Part 1 : the logic deciding a strategy for vectorization and unrolling
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
template<typename Func, typename Evaluator>
|
template<typename Func, typename Derived>
|
||||||
struct redux_traits
|
struct redux_traits
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename find_best_packet<typename Evaluator::Scalar,Evaluator::SizeAtCompileTime>::type PacketType;
|
typedef typename find_best_packet<typename Derived::Scalar,Derived::SizeAtCompileTime>::type PacketType;
|
||||||
enum {
|
enum {
|
||||||
PacketSize = unpacket_traits<PacketType>::size,
|
PacketSize = unpacket_traits<PacketType>::size,
|
||||||
InnerMaxSize = int(Evaluator::IsRowMajor)
|
InnerMaxSize = int(Derived::IsRowMajor)
|
||||||
? Evaluator::MaxColsAtCompileTime
|
? Derived::MaxColsAtCompileTime
|
||||||
: Evaluator::MaxRowsAtCompileTime,
|
: Derived::MaxRowsAtCompileTime
|
||||||
OuterMaxSize = int(Evaluator::IsRowMajor)
|
|
||||||
? Evaluator::MaxRowsAtCompileTime
|
|
||||||
: Evaluator::MaxColsAtCompileTime,
|
|
||||||
SliceVectorizedWork = int(InnerMaxSize)==Dynamic ? Dynamic
|
|
||||||
: int(OuterMaxSize)==Dynamic ? (int(InnerMaxSize)>=int(PacketSize) ? Dynamic : 0)
|
|
||||||
: (int(InnerMaxSize)/int(PacketSize)) * int(OuterMaxSize)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MightVectorize = (int(Evaluator::Flags)&ActualPacketAccessBit)
|
MightVectorize = (int(Derived::Flags)&ActualPacketAccessBit)
|
||||||
&& (functor_traits<Func>::PacketAccess),
|
&& (functor_traits<Func>::PacketAccess),
|
||||||
MayLinearVectorize = bool(MightVectorize) && (int(Evaluator::Flags)&LinearAccessBit),
|
MayLinearVectorize = bool(MightVectorize) && (int(Derived::Flags)&LinearAccessBit),
|
||||||
MaySliceVectorize = bool(MightVectorize) && (int(SliceVectorizedWork)==Dynamic || int(SliceVectorizedWork)>=3)
|
MaySliceVectorize = bool(MightVectorize) && int(InnerMaxSize)>=3*PacketSize
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -57,8 +51,8 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
Cost = Evaluator::SizeAtCompileTime == Dynamic ? HugeCost
|
Cost = Derived::SizeAtCompileTime == Dynamic ? HugeCost
|
||||||
: int(Evaluator::SizeAtCompileTime) * int(Evaluator::CoeffReadCost) + (Evaluator::SizeAtCompileTime-1) * functor_traits<Func>::Cost,
|
: Derived::SizeAtCompileTime * Derived::CoeffReadCost + (Derived::SizeAtCompileTime-1) * functor_traits<Func>::Cost,
|
||||||
UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Traversal) == int(DefaultTraversal) ? 1 : int(PacketSize))
|
UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Traversal) == int(DefaultTraversal) ? 1 : int(PacketSize))
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -70,20 +64,18 @@ public:
|
|||||||
#ifdef EIGEN_DEBUG_ASSIGN
|
#ifdef EIGEN_DEBUG_ASSIGN
|
||||||
static void debug()
|
static void debug()
|
||||||
{
|
{
|
||||||
std::cerr << "Xpr: " << typeid(typename Evaluator::XprType).name() << std::endl;
|
std::cerr << "Xpr: " << typeid(typename Derived::XprType).name() << std::endl;
|
||||||
std::cerr.setf(std::ios::hex, std::ios::basefield);
|
std::cerr.setf(std::ios::hex, std::ios::basefield);
|
||||||
EIGEN_DEBUG_VAR(Evaluator::Flags)
|
EIGEN_DEBUG_VAR(Derived::Flags)
|
||||||
std::cerr.unsetf(std::ios::hex);
|
std::cerr.unsetf(std::ios::hex);
|
||||||
EIGEN_DEBUG_VAR(InnerMaxSize)
|
EIGEN_DEBUG_VAR(InnerMaxSize)
|
||||||
EIGEN_DEBUG_VAR(OuterMaxSize)
|
|
||||||
EIGEN_DEBUG_VAR(SliceVectorizedWork)
|
|
||||||
EIGEN_DEBUG_VAR(PacketSize)
|
EIGEN_DEBUG_VAR(PacketSize)
|
||||||
EIGEN_DEBUG_VAR(MightVectorize)
|
EIGEN_DEBUG_VAR(MightVectorize)
|
||||||
EIGEN_DEBUG_VAR(MayLinearVectorize)
|
EIGEN_DEBUG_VAR(MayLinearVectorize)
|
||||||
EIGEN_DEBUG_VAR(MaySliceVectorize)
|
EIGEN_DEBUG_VAR(MaySliceVectorize)
|
||||||
std::cerr << "Traversal" << " = " << Traversal << " (" << demangle_traversal(Traversal) << ")" << std::endl;
|
EIGEN_DEBUG_VAR(Traversal)
|
||||||
EIGEN_DEBUG_VAR(UnrollingLimit)
|
EIGEN_DEBUG_VAR(UnrollingLimit)
|
||||||
std::cerr << "Unrolling" << " = " << Unrolling << " (" << demangle_unrolling(Unrolling) << ")" << std::endl;
|
EIGEN_DEBUG_VAR(Unrolling)
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -95,86 +87,88 @@ public:
|
|||||||
|
|
||||||
/*** no vectorization ***/
|
/*** no vectorization ***/
|
||||||
|
|
||||||
template<typename Func, typename Evaluator, int Start, int Length>
|
template<typename Func, typename Derived, int Start, int Length>
|
||||||
struct redux_novec_unroller
|
struct redux_novec_unroller
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
HalfLength = Length/2
|
HalfLength = Length/2
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef typename Evaluator::Scalar Scalar;
|
typedef typename Derived::Scalar Scalar;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
static EIGEN_STRONG_INLINE Scalar run(const Evaluator &eval, const Func& func)
|
static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func& func)
|
||||||
{
|
{
|
||||||
return func(redux_novec_unroller<Func, Evaluator, Start, HalfLength>::run(eval,func),
|
return func(redux_novec_unroller<Func, Derived, Start, HalfLength>::run(mat,func),
|
||||||
redux_novec_unroller<Func, Evaluator, Start+HalfLength, Length-HalfLength>::run(eval,func));
|
redux_novec_unroller<Func, Derived, Start+HalfLength, Length-HalfLength>::run(mat,func));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Func, typename Evaluator, int Start>
|
template<typename Func, typename Derived, int Start>
|
||||||
struct redux_novec_unroller<Func, Evaluator, Start, 1>
|
struct redux_novec_unroller<Func, Derived, Start, 1>
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
outer = Start / Evaluator::InnerSizeAtCompileTime,
|
outer = Start / Derived::InnerSizeAtCompileTime,
|
||||||
inner = Start % Evaluator::InnerSizeAtCompileTime
|
inner = Start % Derived::InnerSizeAtCompileTime
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef typename Evaluator::Scalar Scalar;
|
typedef typename Derived::Scalar Scalar;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
static EIGEN_STRONG_INLINE Scalar run(const Evaluator &eval, const Func&)
|
static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func&)
|
||||||
{
|
{
|
||||||
return eval.coeffByOuterInner(outer, inner);
|
return mat.coeffByOuterInner(outer, inner);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is actually dead code and will never be called. It is required
|
// This is actually dead code and will never be called. It is required
|
||||||
// to prevent false warnings regarding failed inlining though
|
// to prevent false warnings regarding failed inlining though
|
||||||
// for 0 length run() will never be called at all.
|
// for 0 length run() will never be called at all.
|
||||||
template<typename Func, typename Evaluator, int Start>
|
template<typename Func, typename Derived, int Start>
|
||||||
struct redux_novec_unroller<Func, Evaluator, Start, 0>
|
struct redux_novec_unroller<Func, Derived, Start, 0>
|
||||||
{
|
{
|
||||||
typedef typename Evaluator::Scalar Scalar;
|
typedef typename Derived::Scalar Scalar;
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
static EIGEN_STRONG_INLINE Scalar run(const Evaluator&, const Func&) { return Scalar(); }
|
static EIGEN_STRONG_INLINE Scalar run(const Derived&, const Func&) { return Scalar(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/*** vectorization ***/
|
/*** vectorization ***/
|
||||||
|
|
||||||
template<typename Func, typename Evaluator, int Start, int Length>
|
template<typename Func, typename Derived, int Start, int Length>
|
||||||
struct redux_vec_unroller
|
struct redux_vec_unroller
|
||||||
{
|
{
|
||||||
template<typename PacketType>
|
enum {
|
||||||
EIGEN_DEVICE_FUNC
|
PacketSize = redux_traits<Func, Derived>::PacketSize,
|
||||||
static EIGEN_STRONG_INLINE PacketType run(const Evaluator &eval, const Func& func)
|
HalfLength = Length/2
|
||||||
{
|
};
|
||||||
enum {
|
|
||||||
PacketSize = unpacket_traits<PacketType>::size,
|
|
||||||
HalfLength = Length/2
|
|
||||||
};
|
|
||||||
|
|
||||||
|
typedef typename Derived::Scalar Scalar;
|
||||||
|
typedef typename redux_traits<Func, Derived>::PacketType PacketScalar;
|
||||||
|
|
||||||
|
static EIGEN_STRONG_INLINE PacketScalar run(const Derived &mat, const Func& func)
|
||||||
|
{
|
||||||
return func.packetOp(
|
return func.packetOp(
|
||||||
redux_vec_unroller<Func, Evaluator, Start, HalfLength>::template run<PacketType>(eval,func),
|
redux_vec_unroller<Func, Derived, Start, HalfLength>::run(mat,func),
|
||||||
redux_vec_unroller<Func, Evaluator, Start+HalfLength, Length-HalfLength>::template run<PacketType>(eval,func) );
|
redux_vec_unroller<Func, Derived, Start+HalfLength, Length-HalfLength>::run(mat,func) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Func, typename Evaluator, int Start>
|
template<typename Func, typename Derived, int Start>
|
||||||
struct redux_vec_unroller<Func, Evaluator, Start, 1>
|
struct redux_vec_unroller<Func, Derived, Start, 1>
|
||||||
{
|
{
|
||||||
template<typename PacketType>
|
enum {
|
||||||
EIGEN_DEVICE_FUNC
|
index = Start * redux_traits<Func, Derived>::PacketSize,
|
||||||
static EIGEN_STRONG_INLINE PacketType run(const Evaluator &eval, const Func&)
|
outer = index / int(Derived::InnerSizeAtCompileTime),
|
||||||
|
inner = index % int(Derived::InnerSizeAtCompileTime),
|
||||||
|
alignment = Derived::Alignment
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef typename Derived::Scalar Scalar;
|
||||||
|
typedef typename redux_traits<Func, Derived>::PacketType PacketScalar;
|
||||||
|
|
||||||
|
static EIGEN_STRONG_INLINE PacketScalar run(const Derived &mat, const Func&)
|
||||||
{
|
{
|
||||||
enum {
|
return mat.template packetByOuterInner<alignment,PacketScalar>(outer, inner);
|
||||||
PacketSize = unpacket_traits<PacketType>::size,
|
|
||||||
index = Start * PacketSize,
|
|
||||||
outer = index / int(Evaluator::InnerSizeAtCompileTime),
|
|
||||||
inner = index % int(Evaluator::InnerSizeAtCompileTime),
|
|
||||||
alignment = Evaluator::Alignment
|
|
||||||
};
|
|
||||||
return eval.template packetByOuterInner<alignment,PacketType>(outer, inner);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -182,65 +176,53 @@ struct redux_vec_unroller<Func, Evaluator, Start, 1>
|
|||||||
* Part 3 : implementation of all cases
|
* Part 3 : implementation of all cases
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
template<typename Func, typename Evaluator,
|
template<typename Func, typename Derived,
|
||||||
int Traversal = redux_traits<Func, Evaluator>::Traversal,
|
int Traversal = redux_traits<Func, Derived>::Traversal,
|
||||||
int Unrolling = redux_traits<Func, Evaluator>::Unrolling
|
int Unrolling = redux_traits<Func, Derived>::Unrolling
|
||||||
>
|
>
|
||||||
struct redux_impl;
|
struct redux_impl;
|
||||||
|
|
||||||
template<typename Func, typename Evaluator>
|
template<typename Func, typename Derived>
|
||||||
struct redux_impl<Func, Evaluator, DefaultTraversal, NoUnrolling>
|
struct redux_impl<Func, Derived, DefaultTraversal, NoUnrolling>
|
||||||
{
|
{
|
||||||
typedef typename Evaluator::Scalar Scalar;
|
typedef typename Derived::Scalar Scalar;
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
template<typename XprType>
|
static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func& func)
|
||||||
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE
|
|
||||||
Scalar run(const Evaluator &eval, const Func& func, const XprType& xpr)
|
|
||||||
{
|
{
|
||||||
eigen_assert(xpr.rows()>0 && xpr.cols()>0 && "you are using an empty matrix");
|
eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix");
|
||||||
Scalar res;
|
Scalar res;
|
||||||
res = eval.coeffByOuterInner(0, 0);
|
res = mat.coeffByOuterInner(0, 0);
|
||||||
for(Index i = 1; i < xpr.innerSize(); ++i)
|
for(Index i = 1; i < mat.innerSize(); ++i)
|
||||||
res = func(res, eval.coeffByOuterInner(0, i));
|
res = func(res, mat.coeffByOuterInner(0, i));
|
||||||
for(Index i = 1; i < xpr.outerSize(); ++i)
|
for(Index i = 1; i < mat.outerSize(); ++i)
|
||||||
for(Index j = 0; j < xpr.innerSize(); ++j)
|
for(Index j = 0; j < mat.innerSize(); ++j)
|
||||||
res = func(res, eval.coeffByOuterInner(i, j));
|
res = func(res, mat.coeffByOuterInner(i, j));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Func, typename Evaluator>
|
template<typename Func, typename Derived>
|
||||||
struct redux_impl<Func,Evaluator, DefaultTraversal, CompleteUnrolling>
|
struct redux_impl<Func,Derived, DefaultTraversal, CompleteUnrolling>
|
||||||
: redux_novec_unroller<Func,Evaluator, 0, Evaluator::SizeAtCompileTime>
|
: public redux_novec_unroller<Func,Derived, 0, Derived::SizeAtCompileTime>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<typename Func, typename Derived>
|
||||||
|
struct redux_impl<Func, Derived, LinearVectorizedTraversal, NoUnrolling>
|
||||||
{
|
{
|
||||||
typedef redux_novec_unroller<Func,Evaluator, 0, Evaluator::SizeAtCompileTime> Base;
|
typedef typename Derived::Scalar Scalar;
|
||||||
typedef typename Evaluator::Scalar Scalar;
|
typedef typename redux_traits<Func, Derived>::PacketType PacketScalar;
|
||||||
template<typename XprType>
|
|
||||||
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE
|
static Scalar run(const Derived &mat, const Func& func)
|
||||||
Scalar run(const Evaluator &eval, const Func& func, const XprType& /*xpr*/)
|
|
||||||
{
|
{
|
||||||
return Base::run(eval,func);
|
const Index size = mat.size();
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Func, typename Evaluator>
|
const Index packetSize = redux_traits<Func, Derived>::PacketSize;
|
||||||
struct redux_impl<Func, Evaluator, LinearVectorizedTraversal, NoUnrolling>
|
|
||||||
{
|
|
||||||
typedef typename Evaluator::Scalar Scalar;
|
|
||||||
typedef typename redux_traits<Func, Evaluator>::PacketType PacketScalar;
|
|
||||||
|
|
||||||
template<typename XprType>
|
|
||||||
static Scalar run(const Evaluator &eval, const Func& func, const XprType& xpr)
|
|
||||||
{
|
|
||||||
const Index size = xpr.size();
|
|
||||||
|
|
||||||
const Index packetSize = redux_traits<Func, Evaluator>::PacketSize;
|
|
||||||
const int packetAlignment = unpacket_traits<PacketScalar>::alignment;
|
const int packetAlignment = unpacket_traits<PacketScalar>::alignment;
|
||||||
enum {
|
enum {
|
||||||
alignment0 = (bool(Evaluator::Flags & DirectAccessBit) && bool(packet_traits<Scalar>::AlignedOnScalar)) ? int(packetAlignment) : int(Unaligned),
|
alignment0 = (bool(Derived::Flags & DirectAccessBit) && bool(packet_traits<Scalar>::AlignedOnScalar)) ? int(packetAlignment) : int(Unaligned),
|
||||||
alignment = EIGEN_PLAIN_ENUM_MAX(alignment0, Evaluator::Alignment)
|
alignment = EIGEN_PLAIN_ENUM_MAX(alignment0, Derived::Alignment)
|
||||||
};
|
};
|
||||||
const Index alignedStart = internal::first_default_aligned(xpr);
|
const Index alignedStart = internal::first_default_aligned(mat.nestedExpression());
|
||||||
const Index alignedSize2 = ((size-alignedStart)/(2*packetSize))*(2*packetSize);
|
const Index alignedSize2 = ((size-alignedStart)/(2*packetSize))*(2*packetSize);
|
||||||
const Index alignedSize = ((size-alignedStart)/(packetSize))*(packetSize);
|
const Index alignedSize = ((size-alignedStart)/(packetSize))*(packetSize);
|
||||||
const Index alignedEnd2 = alignedStart + alignedSize2;
|
const Index alignedEnd2 = alignedStart + alignedSize2;
|
||||||
@@ -248,34 +230,34 @@ struct redux_impl<Func, Evaluator, LinearVectorizedTraversal, NoUnrolling>
|
|||||||
Scalar res;
|
Scalar res;
|
||||||
if(alignedSize)
|
if(alignedSize)
|
||||||
{
|
{
|
||||||
PacketScalar packet_res0 = eval.template packet<alignment,PacketScalar>(alignedStart);
|
PacketScalar packet_res0 = mat.template packet<alignment,PacketScalar>(alignedStart);
|
||||||
if(alignedSize>packetSize) // we have at least two packets to partly unroll the loop
|
if(alignedSize>packetSize) // we have at least two packets to partly unroll the loop
|
||||||
{
|
{
|
||||||
PacketScalar packet_res1 = eval.template packet<alignment,PacketScalar>(alignedStart+packetSize);
|
PacketScalar packet_res1 = mat.template packet<alignment,PacketScalar>(alignedStart+packetSize);
|
||||||
for(Index index = alignedStart + 2*packetSize; index < alignedEnd2; index += 2*packetSize)
|
for(Index index = alignedStart + 2*packetSize; index < alignedEnd2; index += 2*packetSize)
|
||||||
{
|
{
|
||||||
packet_res0 = func.packetOp(packet_res0, eval.template packet<alignment,PacketScalar>(index));
|
packet_res0 = func.packetOp(packet_res0, mat.template packet<alignment,PacketScalar>(index));
|
||||||
packet_res1 = func.packetOp(packet_res1, eval.template packet<alignment,PacketScalar>(index+packetSize));
|
packet_res1 = func.packetOp(packet_res1, mat.template packet<alignment,PacketScalar>(index+packetSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
packet_res0 = func.packetOp(packet_res0,packet_res1);
|
packet_res0 = func.packetOp(packet_res0,packet_res1);
|
||||||
if(alignedEnd>alignedEnd2)
|
if(alignedEnd>alignedEnd2)
|
||||||
packet_res0 = func.packetOp(packet_res0, eval.template packet<alignment,PacketScalar>(alignedEnd2));
|
packet_res0 = func.packetOp(packet_res0, mat.template packet<alignment,PacketScalar>(alignedEnd2));
|
||||||
}
|
}
|
||||||
res = func.predux(packet_res0);
|
res = func.predux(packet_res0);
|
||||||
|
|
||||||
for(Index index = 0; index < alignedStart; ++index)
|
for(Index index = 0; index < alignedStart; ++index)
|
||||||
res = func(res,eval.coeff(index));
|
res = func(res,mat.coeff(index));
|
||||||
|
|
||||||
for(Index index = alignedEnd; index < size; ++index)
|
for(Index index = alignedEnd; index < size; ++index)
|
||||||
res = func(res,eval.coeff(index));
|
res = func(res,mat.coeff(index));
|
||||||
}
|
}
|
||||||
else // too small to vectorize anything.
|
else // too small to vectorize anything.
|
||||||
// since this is dynamic-size hence inefficient anyway for such small sizes, don't try to optimize.
|
// since this is dynamic-size hence inefficient anyway for such small sizes, don't try to optimize.
|
||||||
{
|
{
|
||||||
res = eval.coeff(0);
|
res = mat.coeff(0);
|
||||||
for(Index index = 1; index < size; ++index)
|
for(Index index = 1; index < size; ++index)
|
||||||
res = func(res,eval.coeff(index));
|
res = func(res,mat.coeff(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@@ -283,108 +265,130 @@ struct redux_impl<Func, Evaluator, LinearVectorizedTraversal, NoUnrolling>
|
|||||||
};
|
};
|
||||||
|
|
||||||
// NOTE: for SliceVectorizedTraversal we simply bypass unrolling
|
// NOTE: for SliceVectorizedTraversal we simply bypass unrolling
|
||||||
template<typename Func, typename Evaluator, int Unrolling>
|
template<typename Func, typename Derived, int Unrolling>
|
||||||
struct redux_impl<Func, Evaluator, SliceVectorizedTraversal, Unrolling>
|
struct redux_impl<Func, Derived, SliceVectorizedTraversal, Unrolling>
|
||||||
{
|
{
|
||||||
typedef typename Evaluator::Scalar Scalar;
|
typedef typename Derived::Scalar Scalar;
|
||||||
typedef typename redux_traits<Func, Evaluator>::PacketType PacketType;
|
typedef typename redux_traits<Func, Derived>::PacketType PacketType;
|
||||||
|
|
||||||
template<typename XprType>
|
EIGEN_DEVICE_FUNC static Scalar run(const Derived &mat, const Func& func)
|
||||||
EIGEN_DEVICE_FUNC static Scalar run(const Evaluator &eval, const Func& func, const XprType& xpr)
|
|
||||||
{
|
{
|
||||||
eigen_assert(xpr.rows()>0 && xpr.cols()>0 && "you are using an empty matrix");
|
eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix");
|
||||||
const Index innerSize = xpr.innerSize();
|
const Index innerSize = mat.innerSize();
|
||||||
const Index outerSize = xpr.outerSize();
|
const Index outerSize = mat.outerSize();
|
||||||
enum {
|
enum {
|
||||||
packetSize = redux_traits<Func, Evaluator>::PacketSize
|
packetSize = redux_traits<Func, Derived>::PacketSize
|
||||||
};
|
};
|
||||||
const Index packetedInnerSize = ((innerSize)/packetSize)*packetSize;
|
const Index packetedInnerSize = ((innerSize)/packetSize)*packetSize;
|
||||||
Scalar res;
|
Scalar res;
|
||||||
if(packetedInnerSize)
|
if(packetedInnerSize)
|
||||||
{
|
{
|
||||||
PacketType packet_res = eval.template packet<Unaligned,PacketType>(0,0);
|
PacketType packet_res = mat.template packet<Unaligned,PacketType>(0,0);
|
||||||
for(Index j=0; j<outerSize; ++j)
|
for(Index j=0; j<outerSize; ++j)
|
||||||
for(Index i=(j==0?packetSize:0); i<packetedInnerSize; i+=Index(packetSize))
|
for(Index i=(j==0?packetSize:0); i<packetedInnerSize; i+=Index(packetSize))
|
||||||
packet_res = func.packetOp(packet_res, eval.template packetByOuterInner<Unaligned,PacketType>(j,i));
|
packet_res = func.packetOp(packet_res, mat.template packetByOuterInner<Unaligned,PacketType>(j,i));
|
||||||
|
|
||||||
res = func.predux(packet_res);
|
res = func.predux(packet_res);
|
||||||
for(Index j=0; j<outerSize; ++j)
|
for(Index j=0; j<outerSize; ++j)
|
||||||
for(Index i=packetedInnerSize; i<innerSize; ++i)
|
for(Index i=packetedInnerSize; i<innerSize; ++i)
|
||||||
res = func(res, eval.coeffByOuterInner(j,i));
|
res = func(res, mat.coeffByOuterInner(j,i));
|
||||||
}
|
}
|
||||||
else // too small to vectorize anything.
|
else // too small to vectorize anything.
|
||||||
// since this is dynamic-size hence inefficient anyway for such small sizes, don't try to optimize.
|
// since this is dynamic-size hence inefficient anyway for such small sizes, don't try to optimize.
|
||||||
{
|
{
|
||||||
res = redux_impl<Func, Evaluator, DefaultTraversal, NoUnrolling>::run(eval, func, xpr);
|
res = redux_impl<Func, Derived, DefaultTraversal, NoUnrolling>::run(mat, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Func, typename Evaluator>
|
template<typename Func, typename Derived>
|
||||||
struct redux_impl<Func, Evaluator, LinearVectorizedTraversal, CompleteUnrolling>
|
struct redux_impl<Func, Derived, LinearVectorizedTraversal, CompleteUnrolling>
|
||||||
{
|
{
|
||||||
typedef typename Evaluator::Scalar Scalar;
|
typedef typename Derived::Scalar Scalar;
|
||||||
|
|
||||||
typedef typename redux_traits<Func, Evaluator>::PacketType PacketType;
|
typedef typename redux_traits<Func, Derived>::PacketType PacketScalar;
|
||||||
enum {
|
enum {
|
||||||
PacketSize = redux_traits<Func, Evaluator>::PacketSize,
|
PacketSize = redux_traits<Func, Derived>::PacketSize,
|
||||||
Size = Evaluator::SizeAtCompileTime,
|
Size = Derived::SizeAtCompileTime,
|
||||||
VectorizedSize = (int(Size) / int(PacketSize)) * int(PacketSize)
|
VectorizedSize = (Size / PacketSize) * PacketSize
|
||||||
};
|
};
|
||||||
|
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func& func)
|
||||||
template<typename XprType>
|
|
||||||
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE
|
|
||||||
Scalar run(const Evaluator &eval, const Func& func, const XprType &xpr)
|
|
||||||
{
|
{
|
||||||
EIGEN_ONLY_USED_FOR_DEBUG(xpr)
|
eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix");
|
||||||
eigen_assert(xpr.rows()>0 && xpr.cols()>0 && "you are using an empty matrix");
|
|
||||||
if (VectorizedSize > 0) {
|
if (VectorizedSize > 0) {
|
||||||
Scalar res = func.predux(redux_vec_unroller<Func, Evaluator, 0, Size / PacketSize>::template run<PacketType>(eval,func));
|
Scalar res = func.predux(redux_vec_unroller<Func, Derived, 0, Size / PacketSize>::run(mat,func));
|
||||||
if (VectorizedSize != Size)
|
if (VectorizedSize != Size)
|
||||||
res = func(res,redux_novec_unroller<Func, Evaluator, VectorizedSize, Size-VectorizedSize>::run(eval,func));
|
res = func(res,redux_novec_unroller<Func, Derived, VectorizedSize, Size-VectorizedSize>::run(mat,func));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return redux_novec_unroller<Func, Evaluator, 0, Size>::run(eval,func);
|
return redux_novec_unroller<Func, Derived, 0, Size>::run(mat,func);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// evaluator adaptor
|
// evaluator adaptor
|
||||||
template<typename _XprType>
|
template<typename _XprType>
|
||||||
class redux_evaluator : public internal::evaluator<_XprType>
|
class redux_evaluator
|
||||||
{
|
{
|
||||||
typedef internal::evaluator<_XprType> Base;
|
|
||||||
public:
|
public:
|
||||||
typedef _XprType XprType;
|
typedef _XprType XprType;
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC explicit redux_evaluator(const XprType &xpr) : m_evaluator(xpr), m_xpr(xpr) {}
|
||||||
explicit redux_evaluator(const XprType &xpr) : Base(xpr) {}
|
|
||||||
|
|
||||||
typedef typename XprType::Scalar Scalar;
|
typedef typename XprType::Scalar Scalar;
|
||||||
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
||||||
typedef typename XprType::PacketScalar PacketScalar;
|
typedef typename XprType::PacketScalar PacketScalar;
|
||||||
|
typedef typename XprType::PacketReturnType PacketReturnType;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MaxRowsAtCompileTime = XprType::MaxRowsAtCompileTime,
|
MaxRowsAtCompileTime = XprType::MaxRowsAtCompileTime,
|
||||||
MaxColsAtCompileTime = XprType::MaxColsAtCompileTime,
|
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
|
// TODO we should not remove DirectAccessBit and rather find an elegant way to query the alignment offset at runtime from the evaluator
|
||||||
Flags = Base::Flags & ~DirectAccessBit,
|
Flags = evaluator<XprType>::Flags & ~DirectAccessBit,
|
||||||
IsRowMajor = XprType::IsRowMajor,
|
IsRowMajor = XprType::IsRowMajor,
|
||||||
SizeAtCompileTime = XprType::SizeAtCompileTime,
|
SizeAtCompileTime = XprType::SizeAtCompileTime,
|
||||||
InnerSizeAtCompileTime = XprType::InnerSizeAtCompileTime
|
InnerSizeAtCompileTime = XprType::InnerSizeAtCompileTime,
|
||||||
|
CoeffReadCost = evaluator<XprType>::CoeffReadCost,
|
||||||
|
Alignment = evaluator<XprType>::Alignment
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC Index rows() const { return m_xpr.rows(); }
|
||||||
CoeffReturnType coeffByOuterInner(Index outer, Index inner) const
|
EIGEN_DEVICE_FUNC Index cols() const { return m_xpr.cols(); }
|
||||||
{ return Base::coeff(IsRowMajor ? outer : inner, IsRowMajor ? inner : outer); }
|
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>
|
template<int LoadMode, typename PacketType>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
PacketType packet(Index row, Index col) const
|
||||||
PacketType packetByOuterInner(Index outer, Index inner) const
|
{ return m_evaluator.template packet<LoadMode,PacketType>(row, col); }
|
||||||
{ return Base::template packet<LoadMode,PacketType>(IsRowMajor ? outer : inner, IsRowMajor ? inner : outer); }
|
|
||||||
|
|
||||||
|
template<int LoadMode, typename PacketType>
|
||||||
|
PacketType 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>
|
||||||
|
PacketType 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
|
} // end namespace internal
|
||||||
@@ -399,8 +403,6 @@ public:
|
|||||||
* The template parameter \a BinaryOp is the type of the functor \a func which must be
|
* The template parameter \a BinaryOp is the type of the functor \a func which must be
|
||||||
* an associative operator. Both current C++98 and C++11 functor styles are handled.
|
* an associative operator. Both current C++98 and C++11 functor styles are handled.
|
||||||
*
|
*
|
||||||
* \warning the matrix must be not empty, otherwise an assertion is triggered.
|
|
||||||
*
|
|
||||||
* \sa DenseBase::sum(), DenseBase::minCoeff(), DenseBase::maxCoeff(), MatrixBase::colwise(), MatrixBase::rowwise()
|
* \sa DenseBase::sum(), DenseBase::minCoeff(), DenseBase::maxCoeff(), MatrixBase::colwise(), MatrixBase::rowwise()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
@@ -413,39 +415,27 @@ DenseBase<Derived>::redux(const Func& func) const
|
|||||||
typedef typename internal::redux_evaluator<Derived> ThisEvaluator;
|
typedef typename internal::redux_evaluator<Derived> ThisEvaluator;
|
||||||
ThisEvaluator thisEval(derived());
|
ThisEvaluator thisEval(derived());
|
||||||
|
|
||||||
// The initial expression is passed to the reducer as an additional argument instead of
|
return internal::redux_impl<Func, ThisEvaluator>::run(thisEval, func);
|
||||||
// passing it as a member of redux_evaluator to help
|
|
||||||
return internal::redux_impl<Func, ThisEvaluator>::run(thisEval, func, derived());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the minimum of all coefficients of \c *this.
|
/** \returns the minimum of all coefficients of \c *this.
|
||||||
* In case \c *this contains NaN, NaNPropagation determines the behavior:
|
* \warning the result is undefined if \c *this contains NaN.
|
||||||
* NaNPropagation == PropagateFast : undefined
|
|
||||||
* NaNPropagation == PropagateNaN : result is NaN
|
|
||||||
* NaNPropagation == PropagateNumbers : result is minimum of elements that are not NaN
|
|
||||||
* \warning the matrix must be not empty, otherwise an assertion is triggered.
|
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<int NaNPropagation>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
||||||
DenseBase<Derived>::minCoeff() const
|
DenseBase<Derived>::minCoeff() const
|
||||||
{
|
{
|
||||||
return derived().redux(Eigen::internal::scalar_min_op<Scalar,Scalar, NaNPropagation>());
|
return derived().redux(Eigen::internal::scalar_min_op<Scalar,Scalar>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the maximum of all coefficients of \c *this.
|
/** \returns the maximum of all coefficients of \c *this.
|
||||||
* In case \c *this contains NaN, NaNPropagation determines the behavior:
|
* \warning the result is undefined if \c *this contains NaN.
|
||||||
* NaNPropagation == PropagateFast : undefined
|
|
||||||
* NaNPropagation == PropagateNaN : result is NaN
|
|
||||||
* NaNPropagation == PropagateNumbers : result is maximum of elements that are not NaN
|
|
||||||
* \warning the matrix must be not empty, otherwise an assertion is triggered.
|
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<int NaNPropagation>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
||||||
DenseBase<Derived>::maxCoeff() const
|
DenseBase<Derived>::maxCoeff() const
|
||||||
{
|
{
|
||||||
return derived().redux(Eigen::internal::scalar_max_op<Scalar,Scalar, NaNPropagation>());
|
return derived().redux(Eigen::internal::scalar_max_op<Scalar,Scalar>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the sum of all coefficients of \c *this
|
/** \returns the sum of all coefficients of \c *this
|
||||||
@@ -489,7 +479,7 @@ DenseBase<Derived>::mean() const
|
|||||||
* \sa sum(), mean(), trace()
|
* \sa sum(), mean(), trace()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
||||||
DenseBase<Derived>::prod() const
|
DenseBase<Derived>::prod() const
|
||||||
{
|
{
|
||||||
if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0))
|
if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0))
|
||||||
@@ -504,7 +494,7 @@ DenseBase<Derived>::prod() const
|
|||||||
* \sa diagonal(), sum()
|
* \sa diagonal(), sum()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
||||||
MatrixBase<Derived>::trace() const
|
MatrixBase<Derived>::trace() const
|
||||||
{
|
{
|
||||||
return derived().diagonal().sum();
|
return derived().diagonal().sum();
|
||||||
|
|||||||
@@ -67,12 +67,12 @@ public:
|
|||||||
typedef MapBase<Derived> Base;
|
typedef MapBase<Derived> Base;
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE(RefBase)
|
EIGEN_DENSE_PUBLIC_INTERFACE(RefBase)
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index innerStride() const
|
EIGEN_DEVICE_FUNC inline Index innerStride() const
|
||||||
{
|
{
|
||||||
return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
|
return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index outerStride() const
|
EIGEN_DEVICE_FUNC inline Index outerStride() const
|
||||||
{
|
{
|
||||||
return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
|
return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
|
||||||
: IsVectorAtCompileTime ? this->size()
|
: IsVectorAtCompileTime ? this->size()
|
||||||
@@ -93,115 +93,29 @@ protected:
|
|||||||
|
|
||||||
typedef Stride<StrideType::OuterStrideAtCompileTime,StrideType::InnerStrideAtCompileTime> StrideBase;
|
typedef Stride<StrideType::OuterStrideAtCompileTime,StrideType::InnerStrideAtCompileTime> StrideBase;
|
||||||
|
|
||||||
// Resolves inner stride if default 0.
|
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index resolveInnerStride(Index inner) {
|
|
||||||
return inner == 0 ? 1 : inner;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolves outer stride if default 0.
|
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index resolveOuterStride(Index inner, Index outer, Index rows, Index cols, bool isVectorAtCompileTime, bool isRowMajor) {
|
|
||||||
return outer == 0 ? isVectorAtCompileTime ? inner * rows * cols : isRowMajor ? inner * cols : inner * rows : outer;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns true if construction is valid, false if there is a stride mismatch,
|
|
||||||
// and fails if there is a size mismatch.
|
|
||||||
template<typename Expression>
|
template<typename Expression>
|
||||||
EIGEN_DEVICE_FUNC bool construct(Expression& expr)
|
EIGEN_DEVICE_FUNC void construct(Expression& expr)
|
||||||
{
|
{
|
||||||
// Check matrix sizes. If this is a compile-time vector, we do allow
|
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(PlainObjectType,Expression);
|
||||||
// implicitly transposing.
|
|
||||||
EIGEN_STATIC_ASSERT(
|
|
||||||
EIGEN_PREDICATE_SAME_MATRIX_SIZE(PlainObjectType, Expression)
|
|
||||||
// If it is a vector, the transpose sizes might match.
|
|
||||||
|| ( PlainObjectType::IsVectorAtCompileTime
|
|
||||||
&& ((int(PlainObjectType::RowsAtCompileTime)==Eigen::Dynamic
|
|
||||||
|| int(Expression::ColsAtCompileTime)==Eigen::Dynamic
|
|
||||||
|| int(PlainObjectType::RowsAtCompileTime)==int(Expression::ColsAtCompileTime))
|
|
||||||
&& (int(PlainObjectType::ColsAtCompileTime)==Eigen::Dynamic
|
|
||||||
|| int(Expression::RowsAtCompileTime)==Eigen::Dynamic
|
|
||||||
|| int(PlainObjectType::ColsAtCompileTime)==int(Expression::RowsAtCompileTime)))),
|
|
||||||
YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES
|
|
||||||
)
|
|
||||||
|
|
||||||
// Determine runtime rows and columns.
|
|
||||||
Index rows = expr.rows();
|
|
||||||
Index cols = expr.cols();
|
|
||||||
if(PlainObjectType::RowsAtCompileTime==1)
|
if(PlainObjectType::RowsAtCompileTime==1)
|
||||||
{
|
{
|
||||||
eigen_assert(expr.rows()==1 || expr.cols()==1);
|
eigen_assert(expr.rows()==1 || expr.cols()==1);
|
||||||
rows = 1;
|
::new (static_cast<Base*>(this)) Base(expr.data(), 1, expr.size());
|
||||||
cols = expr.size();
|
|
||||||
}
|
}
|
||||||
else if(PlainObjectType::ColsAtCompileTime==1)
|
else if(PlainObjectType::ColsAtCompileTime==1)
|
||||||
{
|
{
|
||||||
eigen_assert(expr.rows()==1 || expr.cols()==1);
|
eigen_assert(expr.rows()==1 || expr.cols()==1);
|
||||||
rows = expr.size();
|
::new (static_cast<Base*>(this)) Base(expr.data(), expr.size(), 1);
|
||||||
cols = 1;
|
|
||||||
}
|
}
|
||||||
// Verify that the sizes are valid.
|
else
|
||||||
eigen_assert(
|
::new (static_cast<Base*>(this)) Base(expr.data(), expr.rows(), expr.cols());
|
||||||
(PlainObjectType::RowsAtCompileTime == Dynamic) || (PlainObjectType::RowsAtCompileTime == rows));
|
|
||||||
eigen_assert(
|
|
||||||
(PlainObjectType::ColsAtCompileTime == Dynamic) || (PlainObjectType::ColsAtCompileTime == cols));
|
|
||||||
|
|
||||||
|
if(Expression::IsVectorAtCompileTime && (!PlainObjectType::IsVectorAtCompileTime) && ((Expression::Flags&RowMajorBit)!=(PlainObjectType::Flags&RowMajorBit)))
|
||||||
// If this is a vector, we might be transposing, which means that stride should swap.
|
::new (&m_stride) StrideBase(expr.innerStride(), StrideType::InnerStrideAtCompileTime==0?0:1);
|
||||||
const bool transpose = PlainObjectType::IsVectorAtCompileTime && (rows != expr.rows());
|
else
|
||||||
// If the storage format differs, we also need to swap the stride.
|
::new (&m_stride) StrideBase(StrideType::OuterStrideAtCompileTime==0?0:expr.outerStride(),
|
||||||
const bool row_major = ((PlainObjectType::Flags)&RowMajorBit) != 0;
|
StrideType::InnerStrideAtCompileTime==0?0:expr.innerStride());
|
||||||
const bool expr_row_major = (Expression::Flags&RowMajorBit) != 0;
|
|
||||||
const bool storage_differs = (row_major != expr_row_major);
|
|
||||||
|
|
||||||
const bool swap_stride = (transpose != storage_differs);
|
|
||||||
|
|
||||||
// Determine expr's actual strides, resolving any defaults if zero.
|
|
||||||
const Index expr_inner_actual = resolveInnerStride(expr.innerStride());
|
|
||||||
const Index expr_outer_actual = resolveOuterStride(expr_inner_actual,
|
|
||||||
expr.outerStride(),
|
|
||||||
expr.rows(),
|
|
||||||
expr.cols(),
|
|
||||||
Expression::IsVectorAtCompileTime != 0,
|
|
||||||
expr_row_major);
|
|
||||||
|
|
||||||
// If this is a column-major row vector or row-major column vector, the inner-stride
|
|
||||||
// is arbitrary, so set it to either the compile-time inner stride or 1.
|
|
||||||
const bool row_vector = (rows == 1);
|
|
||||||
const bool col_vector = (cols == 1);
|
|
||||||
const Index inner_stride =
|
|
||||||
( (!row_major && row_vector) || (row_major && col_vector) ) ?
|
|
||||||
( StrideType::InnerStrideAtCompileTime > 0 ? Index(StrideType::InnerStrideAtCompileTime) : 1)
|
|
||||||
: swap_stride ? expr_outer_actual : expr_inner_actual;
|
|
||||||
|
|
||||||
// If this is a column-major column vector or row-major row vector, the outer-stride
|
|
||||||
// is arbitrary, so set it to either the compile-time outer stride or vector size.
|
|
||||||
const Index outer_stride =
|
|
||||||
( (!row_major && col_vector) || (row_major && row_vector) ) ?
|
|
||||||
( StrideType::OuterStrideAtCompileTime > 0 ? Index(StrideType::OuterStrideAtCompileTime) : rows * cols * inner_stride)
|
|
||||||
: swap_stride ? expr_inner_actual : expr_outer_actual;
|
|
||||||
|
|
||||||
// Check if given inner/outer strides are compatible with compile-time strides.
|
|
||||||
const bool inner_valid = (StrideType::InnerStrideAtCompileTime == Dynamic)
|
|
||||||
|| (resolveInnerStride(Index(StrideType::InnerStrideAtCompileTime)) == inner_stride);
|
|
||||||
if (!inner_valid) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool outer_valid = (StrideType::OuterStrideAtCompileTime == Dynamic)
|
|
||||||
|| (resolveOuterStride(
|
|
||||||
inner_stride,
|
|
||||||
Index(StrideType::OuterStrideAtCompileTime),
|
|
||||||
rows, cols, PlainObjectType::IsVectorAtCompileTime != 0,
|
|
||||||
row_major)
|
|
||||||
== outer_stride);
|
|
||||||
if (!outer_valid) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
::new (static_cast<Base*>(this)) Base(expr.data(), rows, cols);
|
|
||||||
::new (&m_stride) StrideBase(
|
|
||||||
(StrideType::OuterStrideAtCompileTime == 0) ? 0 : outer_stride,
|
|
||||||
(StrideType::InnerStrideAtCompileTime == 0) ? 0 : inner_stride );
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StrideBase m_stride;
|
StrideBase m_stride;
|
||||||
@@ -273,8 +187,6 @@ protected:
|
|||||||
* void foo(const Ref<MatrixXf,0,Stride<> >& A) { foo_impl(A); }
|
* void foo(const Ref<MatrixXf,0,Stride<> >& A) { foo_impl(A); }
|
||||||
* \endcode
|
* \endcode
|
||||||
*
|
*
|
||||||
* See also the following stackoverflow questions for further references:
|
|
||||||
* - <a href="http://stackoverflow.com/questions/21132538/correct-usage-of-the-eigenref-class">Correct usage of the Eigen::Ref<> class</a>
|
|
||||||
*
|
*
|
||||||
* \sa PlainObjectBase::Map(), \ref TopicStorageOrders
|
* \sa PlainObjectBase::Map(), \ref TopicStorageOrders
|
||||||
*/
|
*/
|
||||||
@@ -298,10 +210,7 @@ template<typename PlainObjectType, int Options, typename StrideType> class Ref
|
|||||||
typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
|
typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
|
EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
|
||||||
// Construction must pass since we will not create temprary storage in the non-const case.
|
Base::construct(expr.derived());
|
||||||
const bool success = Base::construct(expr.derived());
|
|
||||||
EIGEN_UNUSED_VARIABLE(success)
|
|
||||||
eigen_assert(success);
|
|
||||||
}
|
}
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC inline Ref(const DenseBase<Derived>& expr,
|
EIGEN_DEVICE_FUNC inline Ref(const DenseBase<Derived>& expr,
|
||||||
@@ -312,13 +221,10 @@ template<typename PlainObjectType, int Options, typename StrideType> class Ref
|
|||||||
inline Ref(DenseBase<Derived>& expr)
|
inline Ref(DenseBase<Derived>& expr)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT((static_cast<bool>(internal::is_lvalue<Derived>::value)), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
|
EIGEN_STATIC_ASSERT(bool(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
|
||||||
EIGEN_STATIC_ASSERT((static_cast<bool>(Traits::template match<Derived>::MatchAtCompileTime)), STORAGE_LAYOUT_DOES_NOT_MATCH);
|
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);
|
EIGEN_STATIC_ASSERT(!Derived::IsPlainObjectBase,THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
|
||||||
// Construction must pass since we will not create temporary storage in the non-const case.
|
Base::construct(expr.const_cast_derived());
|
||||||
const bool success = Base::construct(expr.const_cast_derived());
|
|
||||||
EIGEN_UNUSED_VARIABLE(success)
|
|
||||||
eigen_assert(success);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Ref)
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Ref)
|
||||||
@@ -359,10 +265,7 @@ template<typename TPlainObjectType, int Options, typename StrideType> class Ref<
|
|||||||
template<typename Expression>
|
template<typename Expression>
|
||||||
EIGEN_DEVICE_FUNC void construct(const Expression& expr,internal::true_type)
|
EIGEN_DEVICE_FUNC void construct(const Expression& expr,internal::true_type)
|
||||||
{
|
{
|
||||||
// Check if we can use the underlying expr's storage directly, otherwise call the copy version.
|
Base::construct(expr);
|
||||||
if (!Base::construct(expr)) {
|
|
||||||
construct(expr, internal::false_type());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Expression>
|
template<typename Expression>
|
||||||
|
|||||||
@@ -88,9 +88,9 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
|
|||||||
THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE)
|
THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE)
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index rows() const { return m_matrix.rows() * m_rowFactor.value(); }
|
inline Index rows() const { return m_matrix.rows() * m_rowFactor.value(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index cols() const { return m_matrix.cols() * m_colFactor.value(); }
|
inline Index cols() const { return m_matrix.cols() * m_colFactor.value(); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
|
|||||||
@@ -1,454 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008-2017 Gael Guennebaud <gael.guennebaud@inria.fr>
|
|
||||||
// Copyright (C) 2014 yoco <peter.xiau@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_RESHAPED_H
|
|
||||||
#define EIGEN_RESHAPED_H
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
/** \class Reshaped
|
|
||||||
* \ingroup Core_Module
|
|
||||||
*
|
|
||||||
* \brief Expression of a fixed-size or dynamic-size reshape
|
|
||||||
*
|
|
||||||
* \tparam XprType the type of the expression in which we are taking a reshape
|
|
||||||
* \tparam Rows the number of rows of the reshape we are taking at compile time (optional)
|
|
||||||
* \tparam Cols the number of columns of the reshape we are taking at compile time (optional)
|
|
||||||
* \tparam Order can be ColMajor or RowMajor, default is ColMajor.
|
|
||||||
*
|
|
||||||
* This class represents an expression of either a fixed-size or dynamic-size reshape.
|
|
||||||
* It is the return type of DenseBase::reshaped(NRowsType,NColsType) and
|
|
||||||
* most of the time this is the only way it is used.
|
|
||||||
*
|
|
||||||
* However, in C++98, if you want to directly maniputate reshaped expressions,
|
|
||||||
* for instance if you want to write a function returning such an expression, you
|
|
||||||
* will need to use this class. In C++11, it is advised to use the \em auto
|
|
||||||
* keyword for such use cases.
|
|
||||||
*
|
|
||||||
* Here is an example illustrating the dynamic case:
|
|
||||||
* \include class_Reshaped.cpp
|
|
||||||
* Output: \verbinclude class_Reshaped.out
|
|
||||||
*
|
|
||||||
* Here is an example illustrating the fixed-size case:
|
|
||||||
* \include class_FixedReshaped.cpp
|
|
||||||
* Output: \verbinclude class_FixedReshaped.out
|
|
||||||
*
|
|
||||||
* \sa DenseBase::reshaped(NRowsType,NColsType)
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template<typename XprType, int Rows, int Cols, int Order>
|
|
||||||
struct traits<Reshaped<XprType, Rows, Cols, Order> > : traits<XprType>
|
|
||||||
{
|
|
||||||
typedef typename traits<XprType>::Scalar Scalar;
|
|
||||||
typedef typename traits<XprType>::StorageKind StorageKind;
|
|
||||||
typedef typename traits<XprType>::XprKind XprKind;
|
|
||||||
enum{
|
|
||||||
MatrixRows = traits<XprType>::RowsAtCompileTime,
|
|
||||||
MatrixCols = traits<XprType>::ColsAtCompileTime,
|
|
||||||
RowsAtCompileTime = Rows,
|
|
||||||
ColsAtCompileTime = Cols,
|
|
||||||
MaxRowsAtCompileTime = Rows,
|
|
||||||
MaxColsAtCompileTime = Cols,
|
|
||||||
XpxStorageOrder = ((int(traits<XprType>::Flags) & RowMajorBit) == RowMajorBit) ? RowMajor : ColMajor,
|
|
||||||
ReshapedStorageOrder = (RowsAtCompileTime == 1 && ColsAtCompileTime != 1) ? RowMajor
|
|
||||||
: (ColsAtCompileTime == 1 && RowsAtCompileTime != 1) ? ColMajor
|
|
||||||
: XpxStorageOrder,
|
|
||||||
HasSameStorageOrderAsXprType = (ReshapedStorageOrder == XpxStorageOrder),
|
|
||||||
InnerSize = (ReshapedStorageOrder==int(RowMajor)) ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
|
|
||||||
InnerStrideAtCompileTime = HasSameStorageOrderAsXprType
|
|
||||||
? int(inner_stride_at_compile_time<XprType>::ret)
|
|
||||||
: Dynamic,
|
|
||||||
OuterStrideAtCompileTime = Dynamic,
|
|
||||||
|
|
||||||
HasDirectAccess = internal::has_direct_access<XprType>::ret
|
|
||||||
&& (Order==int(XpxStorageOrder))
|
|
||||||
&& ((evaluator<XprType>::Flags&LinearAccessBit)==LinearAccessBit),
|
|
||||||
|
|
||||||
MaskPacketAccessBit = (InnerSize == Dynamic || (InnerSize % packet_traits<Scalar>::size) == 0)
|
|
||||||
&& (InnerStrideAtCompileTime == 1)
|
|
||||||
? PacketAccessBit : 0,
|
|
||||||
//MaskAlignedBit = ((OuterStrideAtCompileTime!=Dynamic) && (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % 16) == 0)) ? AlignedBit : 0,
|
|
||||||
FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0,
|
|
||||||
FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
|
|
||||||
FlagsRowMajorBit = (ReshapedStorageOrder==int(RowMajor)) ? RowMajorBit : 0,
|
|
||||||
FlagsDirectAccessBit = HasDirectAccess ? DirectAccessBit : 0,
|
|
||||||
Flags0 = traits<XprType>::Flags & ( (HereditaryBits & ~RowMajorBit) | MaskPacketAccessBit),
|
|
||||||
|
|
||||||
Flags = (Flags0 | FlagsLinearAccessBit | FlagsLvalueBit | FlagsRowMajorBit | FlagsDirectAccessBit)
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename XprType, int Rows, int Cols, int Order, bool HasDirectAccess> class ReshapedImpl_dense;
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
|
|
||||||
template<typename XprType, int Rows, int Cols, int Order, typename StorageKind> class ReshapedImpl;
|
|
||||||
|
|
||||||
template<typename XprType, int Rows, int Cols, int Order> class Reshaped
|
|
||||||
: public ReshapedImpl<XprType, Rows, Cols, Order, typename internal::traits<XprType>::StorageKind>
|
|
||||||
{
|
|
||||||
typedef ReshapedImpl<XprType, Rows, Cols, Order, typename internal::traits<XprType>::StorageKind> Impl;
|
|
||||||
public:
|
|
||||||
//typedef typename Impl::Base Base;
|
|
||||||
typedef Impl Base;
|
|
||||||
EIGEN_GENERIC_PUBLIC_INTERFACE(Reshaped)
|
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reshaped)
|
|
||||||
|
|
||||||
/** Fixed-size constructor
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline Reshaped(XprType& xpr)
|
|
||||||
: Impl(xpr)
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
|
|
||||||
eigen_assert(Rows * Cols == xpr.rows() * xpr.cols());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Dynamic-size constructor
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline Reshaped(XprType& xpr,
|
|
||||||
Index reshapeRows, Index reshapeCols)
|
|
||||||
: Impl(xpr, reshapeRows, reshapeCols)
|
|
||||||
{
|
|
||||||
eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==reshapeRows)
|
|
||||||
&& (ColsAtCompileTime==Dynamic || ColsAtCompileTime==reshapeCols));
|
|
||||||
eigen_assert(reshapeRows * reshapeCols == xpr.rows() * xpr.cols());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// The generic default implementation for dense reshape simply forward to the internal::ReshapedImpl_dense
|
|
||||||
// that must be specialized for direct and non-direct access...
|
|
||||||
template<typename XprType, int Rows, int Cols, int Order>
|
|
||||||
class ReshapedImpl<XprType, Rows, Cols, Order, Dense>
|
|
||||||
: public internal::ReshapedImpl_dense<XprType, Rows, Cols, Order,internal::traits<Reshaped<XprType,Rows,Cols,Order> >::HasDirectAccess>
|
|
||||||
{
|
|
||||||
typedef internal::ReshapedImpl_dense<XprType, Rows, Cols, Order,internal::traits<Reshaped<XprType,Rows,Cols,Order> >::HasDirectAccess> Impl;
|
|
||||||
public:
|
|
||||||
typedef Impl Base;
|
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ReshapedImpl)
|
|
||||||
EIGEN_DEVICE_FUNC inline ReshapedImpl(XprType& xpr) : Impl(xpr) {}
|
|
||||||
EIGEN_DEVICE_FUNC inline ReshapedImpl(XprType& xpr, Index reshapeRows, Index reshapeCols)
|
|
||||||
: Impl(xpr, reshapeRows, reshapeCols) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
/** \internal Internal implementation of dense Reshaped in the general case. */
|
|
||||||
template<typename XprType, int Rows, int Cols, int Order>
|
|
||||||
class ReshapedImpl_dense<XprType,Rows,Cols,Order,false>
|
|
||||||
: public internal::dense_xpr_base<Reshaped<XprType, Rows, Cols, Order> >::type
|
|
||||||
{
|
|
||||||
typedef Reshaped<XprType, Rows, Cols, Order> ReshapedType;
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef typename internal::dense_xpr_base<ReshapedType>::type Base;
|
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE(ReshapedType)
|
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ReshapedImpl_dense)
|
|
||||||
|
|
||||||
typedef typename internal::ref_selector<XprType>::non_const_type MatrixTypeNested;
|
|
||||||
typedef typename internal::remove_all<XprType>::type NestedExpression;
|
|
||||||
|
|
||||||
class InnerIterator;
|
|
||||||
|
|
||||||
/** Fixed-size constructor
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline ReshapedImpl_dense(XprType& xpr)
|
|
||||||
: m_xpr(xpr), m_rows(Rows), m_cols(Cols)
|
|
||||||
{}
|
|
||||||
|
|
||||||
/** Dynamic-size constructor
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline ReshapedImpl_dense(XprType& xpr, Index nRows, Index nCols)
|
|
||||||
: m_xpr(xpr), m_rows(nRows), m_cols(nCols)
|
|
||||||
{}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC Index rows() const { return m_rows; }
|
|
||||||
EIGEN_DEVICE_FUNC Index cols() const { return m_cols; }
|
|
||||||
|
|
||||||
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
/** \sa MapBase::data() */
|
|
||||||
EIGEN_DEVICE_FUNC inline const Scalar* data() const;
|
|
||||||
EIGEN_DEVICE_FUNC inline Index innerStride() const;
|
|
||||||
EIGEN_DEVICE_FUNC inline Index outerStride() const;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \returns the nested expression */
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
const typename internal::remove_all<XprType>::type&
|
|
||||||
nestedExpression() const { return m_xpr; }
|
|
||||||
|
|
||||||
/** \returns the nested expression */
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
typename internal::remove_reference<XprType>::type&
|
|
||||||
nestedExpression() { return m_xpr; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
MatrixTypeNested m_xpr;
|
|
||||||
const internal::variable_if_dynamic<Index, Rows> m_rows;
|
|
||||||
const internal::variable_if_dynamic<Index, Cols> m_cols;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/** \internal Internal implementation of dense Reshaped in the direct access case. */
|
|
||||||
template<typename XprType, int Rows, int Cols, int Order>
|
|
||||||
class ReshapedImpl_dense<XprType, Rows, Cols, Order, true>
|
|
||||||
: public MapBase<Reshaped<XprType, Rows, Cols, Order> >
|
|
||||||
{
|
|
||||||
typedef Reshaped<XprType, Rows, Cols, Order> ReshapedType;
|
|
||||||
typedef typename internal::ref_selector<XprType>::non_const_type XprTypeNested;
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef MapBase<ReshapedType> Base;
|
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE(ReshapedType)
|
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ReshapedImpl_dense)
|
|
||||||
|
|
||||||
/** Fixed-size constructor
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline ReshapedImpl_dense(XprType& xpr)
|
|
||||||
: Base(xpr.data()), m_xpr(xpr)
|
|
||||||
{}
|
|
||||||
|
|
||||||
/** Dynamic-size constructor
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline ReshapedImpl_dense(XprType& xpr, Index nRows, Index nCols)
|
|
||||||
: Base(xpr.data(), nRows, nCols),
|
|
||||||
m_xpr(xpr)
|
|
||||||
{}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
const typename internal::remove_all<XprTypeNested>::type& nestedExpression() const
|
|
||||||
{
|
|
||||||
return m_xpr;
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
XprType& nestedExpression() { return m_xpr; }
|
|
||||||
|
|
||||||
/** \sa MapBase::innerStride() */
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
|
||||||
inline Index innerStride() const
|
|
||||||
{
|
|
||||||
return m_xpr.innerStride();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \sa MapBase::outerStride() */
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
|
||||||
inline Index outerStride() const
|
|
||||||
{
|
|
||||||
return (((Flags&RowMajorBit)==RowMajorBit) ? this->cols() : this->rows()) * m_xpr.innerStride();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
XprTypeNested m_xpr;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Evaluators
|
|
||||||
template<typename ArgType, int Rows, int Cols, int Order, bool HasDirectAccess> struct reshaped_evaluator;
|
|
||||||
|
|
||||||
template<typename ArgType, int Rows, int Cols, int Order>
|
|
||||||
struct evaluator<Reshaped<ArgType, Rows, Cols, Order> >
|
|
||||||
: reshaped_evaluator<ArgType, Rows, Cols, Order, traits<Reshaped<ArgType,Rows,Cols,Order> >::HasDirectAccess>
|
|
||||||
{
|
|
||||||
typedef Reshaped<ArgType, Rows, Cols, Order> XprType;
|
|
||||||
typedef typename XprType::Scalar Scalar;
|
|
||||||
// TODO: should check for smaller packet types
|
|
||||||
typedef typename packet_traits<Scalar>::type PacketScalar;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
|
|
||||||
HasDirectAccess = traits<XprType>::HasDirectAccess,
|
|
||||||
|
|
||||||
// RowsAtCompileTime = traits<XprType>::RowsAtCompileTime,
|
|
||||||
// ColsAtCompileTime = traits<XprType>::ColsAtCompileTime,
|
|
||||||
// MaxRowsAtCompileTime = traits<XprType>::MaxRowsAtCompileTime,
|
|
||||||
// MaxColsAtCompileTime = traits<XprType>::MaxColsAtCompileTime,
|
|
||||||
//
|
|
||||||
// InnerStrideAtCompileTime = traits<XprType>::HasSameStorageOrderAsXprType
|
|
||||||
// ? int(inner_stride_at_compile_time<ArgType>::ret)
|
|
||||||
// : Dynamic,
|
|
||||||
// OuterStrideAtCompileTime = Dynamic,
|
|
||||||
|
|
||||||
FlagsLinearAccessBit = (traits<XprType>::RowsAtCompileTime == 1 || traits<XprType>::ColsAtCompileTime == 1 || HasDirectAccess) ? LinearAccessBit : 0,
|
|
||||||
FlagsRowMajorBit = (traits<XprType>::ReshapedStorageOrder==int(RowMajor)) ? RowMajorBit : 0,
|
|
||||||
FlagsDirectAccessBit = HasDirectAccess ? DirectAccessBit : 0,
|
|
||||||
Flags0 = evaluator<ArgType>::Flags & (HereditaryBits & ~RowMajorBit),
|
|
||||||
Flags = Flags0 | FlagsLinearAccessBit | FlagsRowMajorBit | FlagsDirectAccessBit,
|
|
||||||
|
|
||||||
PacketAlignment = unpacket_traits<PacketScalar>::alignment,
|
|
||||||
Alignment = evaluator<ArgType>::Alignment
|
|
||||||
};
|
|
||||||
typedef reshaped_evaluator<ArgType, Rows, Cols, Order, HasDirectAccess> reshaped_evaluator_type;
|
|
||||||
EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr) : reshaped_evaluator_type(xpr)
|
|
||||||
{
|
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename ArgType, int Rows, int Cols, int Order>
|
|
||||||
struct reshaped_evaluator<ArgType, Rows, Cols, Order, /* HasDirectAccess */ false>
|
|
||||||
: evaluator_base<Reshaped<ArgType, Rows, Cols, Order> >
|
|
||||||
{
|
|
||||||
typedef Reshaped<ArgType, Rows, Cols, Order> XprType;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
CoeffReadCost = evaluator<ArgType>::CoeffReadCost /* TODO + cost of index computations */,
|
|
||||||
|
|
||||||
Flags = (evaluator<ArgType>::Flags & (HereditaryBits /*| LinearAccessBit | DirectAccessBit*/)),
|
|
||||||
|
|
||||||
Alignment = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit reshaped_evaluator(const XprType& xpr) : m_argImpl(xpr.nestedExpression()), m_xpr(xpr)
|
|
||||||
{
|
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef typename XprType::Scalar Scalar;
|
|
||||||
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
|
||||||
|
|
||||||
typedef std::pair<Index, Index> RowCol;
|
|
||||||
|
|
||||||
inline RowCol index_remap(Index rowId, Index colId) const
|
|
||||||
{
|
|
||||||
if(Order==ColMajor)
|
|
||||||
{
|
|
||||||
const Index nth_elem_idx = colId * m_xpr.rows() + rowId;
|
|
||||||
return RowCol(nth_elem_idx % m_xpr.nestedExpression().rows(),
|
|
||||||
nth_elem_idx / m_xpr.nestedExpression().rows());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const Index nth_elem_idx = colId + rowId * m_xpr.cols();
|
|
||||||
return RowCol(nth_elem_idx / m_xpr.nestedExpression().cols(),
|
|
||||||
nth_elem_idx % m_xpr.nestedExpression().cols());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline Scalar& coeffRef(Index rowId, Index colId)
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT_LVALUE(XprType)
|
|
||||||
const RowCol row_col = index_remap(rowId, colId);
|
|
||||||
return m_argImpl.coeffRef(row_col.first, row_col.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline const Scalar& coeffRef(Index rowId, Index colId) const
|
|
||||||
{
|
|
||||||
const RowCol row_col = index_remap(rowId, colId);
|
|
||||||
return m_argImpl.coeffRef(row_col.first, row_col.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index rowId, Index colId) const
|
|
||||||
{
|
|
||||||
const RowCol row_col = index_remap(rowId, colId);
|
|
||||||
return m_argImpl.coeff(row_col.first, row_col.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline Scalar& coeffRef(Index index)
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT_LVALUE(XprType)
|
|
||||||
const RowCol row_col = index_remap(Rows == 1 ? 0 : index,
|
|
||||||
Rows == 1 ? index : 0);
|
|
||||||
return m_argImpl.coeffRef(row_col.first, row_col.second);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline const Scalar& coeffRef(Index index) const
|
|
||||||
{
|
|
||||||
const RowCol row_col = index_remap(Rows == 1 ? 0 : index,
|
|
||||||
Rows == 1 ? index : 0);
|
|
||||||
return m_argImpl.coeffRef(row_col.first, row_col.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline const CoeffReturnType coeff(Index index) const
|
|
||||||
{
|
|
||||||
const RowCol row_col = index_remap(Rows == 1 ? 0 : index,
|
|
||||||
Rows == 1 ? index : 0);
|
|
||||||
return m_argImpl.coeff(row_col.first, row_col.second);
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
template<int LoadMode>
|
|
||||||
inline PacketScalar packet(Index rowId, Index colId) const
|
|
||||||
{
|
|
||||||
const RowCol row_col = index_remap(rowId, colId);
|
|
||||||
return m_argImpl.template packet<Unaligned>(row_col.first, row_col.second);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int LoadMode>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline void writePacket(Index rowId, Index colId, const PacketScalar& val)
|
|
||||||
{
|
|
||||||
const RowCol row_col = index_remap(rowId, colId);
|
|
||||||
m_argImpl.const_cast_derived().template writePacket<Unaligned>
|
|
||||||
(row_col.first, row_col.second, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int LoadMode>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline PacketScalar packet(Index index) const
|
|
||||||
{
|
|
||||||
const RowCol row_col = index_remap(RowsAtCompileTime == 1 ? 0 : index,
|
|
||||||
RowsAtCompileTime == 1 ? index : 0);
|
|
||||||
return m_argImpl.template packet<Unaligned>(row_col.first, row_col.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int LoadMode>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline void writePacket(Index index, const PacketScalar& val)
|
|
||||||
{
|
|
||||||
const RowCol row_col = index_remap(RowsAtCompileTime == 1 ? 0 : index,
|
|
||||||
RowsAtCompileTime == 1 ? index : 0);
|
|
||||||
return m_argImpl.template packet<Unaligned>(row_col.first, row_col.second, val);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
protected:
|
|
||||||
|
|
||||||
evaluator<ArgType> m_argImpl;
|
|
||||||
const XprType& m_xpr;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename ArgType, int Rows, int Cols, int Order>
|
|
||||||
struct reshaped_evaluator<ArgType, Rows, Cols, Order, /* HasDirectAccess */ true>
|
|
||||||
: mapbase_evaluator<Reshaped<ArgType, Rows, Cols, Order>,
|
|
||||||
typename Reshaped<ArgType, Rows, Cols, Order>::PlainObject>
|
|
||||||
{
|
|
||||||
typedef Reshaped<ArgType, Rows, Cols, Order> XprType;
|
|
||||||
typedef typename XprType::Scalar Scalar;
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit reshaped_evaluator(const XprType& xpr)
|
|
||||||
: mapbase_evaluator<XprType, typename XprType::PlainObject>(xpr)
|
|
||||||
{
|
|
||||||
// TODO: for the 3.4 release, this should be turned to an internal assertion, but let's keep it as is for the beta lifetime
|
|
||||||
eigen_assert(((internal::UIntPtr(xpr.data()) % EIGEN_PLAIN_ENUM_MAX(1,evaluator<XprType>::Alignment)) == 0) && "data is not aligned");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_RESHAPED_H
|
|
||||||
@@ -60,10 +60,8 @@ template<typename Derived> class ReturnByValue
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline void evalTo(Dest& dst) const
|
inline void evalTo(Dest& dst) const
|
||||||
{ static_cast<const Derived*>(this)->evalTo(dst); }
|
{ static_cast<const Derived*>(this)->evalTo(dst); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC inline Index rows() const { return static_cast<const Derived*>(this)->rows(); }
|
||||||
inline Index rows() const EIGEN_NOEXCEPT { return static_cast<const Derived*>(this)->rows(); }
|
EIGEN_DEVICE_FUNC inline Index cols() const { return static_cast<const Derived*>(this)->cols(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
|
||||||
inline Index cols() const EIGEN_NOEXCEPT { return static_cast<const Derived*>(this)->cols(); }
|
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#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
|
#define Unusable YOU_ARE_TRYING_TO_ACCESS_A_SINGLE_COEFFICIENT_IN_A_SPECIAL_EXPRESSION_WHERE_THAT_IS_NOT_ALLOWED_BECAUSE_THAT_WOULD_BE_INEFFICIENT
|
||||||
|
|||||||
@@ -89,10 +89,8 @@ template<typename MatrixType, int Direction> class Reverse
|
|||||||
|
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reverse)
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reverse)
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC inline Index rows() const { return m_matrix.rows(); }
|
||||||
inline Index rows() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
|
EIGEN_DEVICE_FUNC inline Index cols() const { return m_matrix.cols(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
|
||||||
inline Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline Index innerStride() const
|
EIGEN_DEVICE_FUNC inline Index innerStride() const
|
||||||
{
|
{
|
||||||
@@ -173,10 +171,8 @@ struct vectorwise_reverse_inplace_impl<Vertical>
|
|||||||
template<typename ExpressionType>
|
template<typename ExpressionType>
|
||||||
static void run(ExpressionType &xpr)
|
static void run(ExpressionType &xpr)
|
||||||
{
|
{
|
||||||
const int HalfAtCompileTime = ExpressionType::RowsAtCompileTime==Dynamic?Dynamic:ExpressionType::RowsAtCompileTime/2;
|
|
||||||
Index half = xpr.rows()/2;
|
Index half = xpr.rows()/2;
|
||||||
xpr.topRows(fix<HalfAtCompileTime>(half))
|
xpr.topRows(half).swap(xpr.bottomRows(half).colwise().reverse());
|
||||||
.swap(xpr.bottomRows(fix<HalfAtCompileTime>(half)).colwise().reverse());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -186,10 +182,8 @@ struct vectorwise_reverse_inplace_impl<Horizontal>
|
|||||||
template<typename ExpressionType>
|
template<typename ExpressionType>
|
||||||
static void run(ExpressionType &xpr)
|
static void run(ExpressionType &xpr)
|
||||||
{
|
{
|
||||||
const int HalfAtCompileTime = ExpressionType::ColsAtCompileTime==Dynamic?Dynamic:ExpressionType::ColsAtCompileTime/2;
|
|
||||||
Index half = xpr.cols()/2;
|
Index half = xpr.cols()/2;
|
||||||
xpr.leftCols(fix<HalfAtCompileTime>(half))
|
xpr.leftCols(half).swap(xpr.rightCols(half).rowwise().reverse());
|
||||||
.swap(xpr.rightCols(fix<HalfAtCompileTime>(half)).rowwise().reverse());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -209,7 +203,7 @@ struct vectorwise_reverse_inplace_impl<Horizontal>
|
|||||||
template<typename ExpressionType, int Direction>
|
template<typename ExpressionType, int Direction>
|
||||||
EIGEN_DEVICE_FUNC void VectorwiseOp<ExpressionType,Direction>::reverseInPlace()
|
EIGEN_DEVICE_FUNC void VectorwiseOp<ExpressionType,Direction>::reverseInPlace()
|
||||||
{
|
{
|
||||||
internal::vectorwise_reverse_inplace_impl<Direction>::run(m_matrix);
|
internal::vectorwise_reverse_inplace_impl<Direction>::run(_expression().const_cast_derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|||||||
@@ -67,10 +67,8 @@ class Select : public internal::dense_xpr_base< Select<ConditionMatrixType, Then
|
|||||||
eigen_assert(m_condition.cols() == m_then.cols() && m_condition.cols() == m_else.cols());
|
eigen_assert(m_condition.cols() == m_then.cols() && m_condition.cols() == m_else.cols());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
inline EIGEN_DEVICE_FUNC Index rows() const { return m_condition.rows(); }
|
||||||
Index rows() const EIGEN_NOEXCEPT { return m_condition.rows(); }
|
inline EIGEN_DEVICE_FUNC Index cols() const { return m_condition.cols(); }
|
||||||
inline EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
|
||||||
Index cols() const EIGEN_NOEXCEPT { return m_condition.cols(); }
|
|
||||||
|
|
||||||
inline EIGEN_DEVICE_FUNC
|
inline EIGEN_DEVICE_FUNC
|
||||||
const Scalar coeff(Index i, Index j) const
|
const Scalar coeff(Index i, Index j) const
|
||||||
@@ -122,7 +120,7 @@ class Select : public internal::dense_xpr_base< Select<ConditionMatrixType, Then
|
|||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename ThenDerived,typename ElseDerived>
|
template<typename ThenDerived,typename ElseDerived>
|
||||||
inline EIGEN_DEVICE_FUNC const Select<Derived,ThenDerived,ElseDerived>
|
inline const Select<Derived,ThenDerived,ElseDerived>
|
||||||
DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
|
DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
|
||||||
const DenseBase<ElseDerived>& elseMatrix) const
|
const DenseBase<ElseDerived>& elseMatrix) const
|
||||||
{
|
{
|
||||||
@@ -136,7 +134,7 @@ DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
|
|||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename ThenDerived>
|
template<typename ThenDerived>
|
||||||
inline EIGEN_DEVICE_FUNC const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
|
inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
|
||||||
DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
|
DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
|
||||||
const typename ThenDerived::Scalar& elseScalar) const
|
const typename ThenDerived::Scalar& elseScalar) const
|
||||||
{
|
{
|
||||||
@@ -151,7 +149,7 @@ DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
|
|||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename ElseDerived>
|
template<typename ElseDerived>
|
||||||
inline EIGEN_DEVICE_FUNC const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
|
inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
|
||||||
DenseBase<Derived>::select(const typename ElseDerived::Scalar& thenScalar,
|
DenseBase<Derived>::select(const typename ElseDerived::Scalar& thenScalar,
|
||||||
const DenseBase<ElseDerived>& elseMatrix) const
|
const DenseBase<ElseDerived>& elseMatrix) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -61,12 +61,11 @@ template<typename _MatrixType, unsigned int UpLo> class SelfAdjointView
|
|||||||
typedef typename internal::traits<SelfAdjointView>::Scalar Scalar;
|
typedef typename internal::traits<SelfAdjointView>::Scalar Scalar;
|
||||||
typedef typename MatrixType::StorageIndex StorageIndex;
|
typedef typename MatrixType::StorageIndex StorageIndex;
|
||||||
typedef typename internal::remove_all<typename MatrixType::ConjugateReturnType>::type MatrixConjugateReturnType;
|
typedef typename internal::remove_all<typename MatrixType::ConjugateReturnType>::type MatrixConjugateReturnType;
|
||||||
typedef SelfAdjointView<typename internal::add_const<MatrixType>::type, UpLo> ConstSelfAdjointView;
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
Mode = internal::traits<SelfAdjointView>::Mode,
|
Mode = internal::traits<SelfAdjointView>::Mode,
|
||||||
Flags = internal::traits<SelfAdjointView>::Flags,
|
Flags = internal::traits<SelfAdjointView>::Flags,
|
||||||
TransposeMode = ((int(Mode) & int(Upper)) ? Lower : 0) | ((int(Mode) & int(Lower)) ? Upper : 0)
|
TransposeMode = ((Mode & Upper) ? Lower : 0) | ((Mode & Lower) ? Upper : 0)
|
||||||
};
|
};
|
||||||
typedef typename MatrixType::PlainObject PlainObject;
|
typedef typename MatrixType::PlainObject PlainObject;
|
||||||
|
|
||||||
@@ -76,14 +75,14 @@ template<typename _MatrixType, unsigned int UpLo> class SelfAdjointView
|
|||||||
EIGEN_STATIC_ASSERT(UpLo==Lower || UpLo==Upper,SELFADJOINTVIEW_ACCEPTS_UPPER_AND_LOWER_MODE_ONLY);
|
EIGEN_STATIC_ASSERT(UpLo==Lower || UpLo==Upper,SELFADJOINTVIEW_ACCEPTS_UPPER_AND_LOWER_MODE_ONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index rows() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
|
inline Index rows() const { return m_matrix.rows(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
|
inline Index cols() const { return m_matrix.cols(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index outerStride() const EIGEN_NOEXCEPT { return m_matrix.outerStride(); }
|
inline Index outerStride() const { return m_matrix.outerStride(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index innerStride() const EIGEN_NOEXCEPT { return m_matrix.innerStride(); }
|
inline Index innerStride() const { return m_matrix.innerStride(); }
|
||||||
|
|
||||||
/** \sa MatrixBase::coeff()
|
/** \sa MatrixBase::coeff()
|
||||||
* \warning the coordinates must fit into the referenced triangular part
|
* \warning the coordinates must fit into the referenced triangular part
|
||||||
@@ -198,18 +197,6 @@ template<typename _MatrixType, unsigned int UpLo> class SelfAdjointView
|
|||||||
inline const ConjugateReturnType conjugate() const
|
inline const ConjugateReturnType conjugate() const
|
||||||
{ return ConjugateReturnType(m_matrix.conjugate()); }
|
{ return ConjugateReturnType(m_matrix.conjugate()); }
|
||||||
|
|
||||||
/** \returns an expression of the complex conjugate of \c *this if Cond==true,
|
|
||||||
* returns \c *this otherwise.
|
|
||||||
*/
|
|
||||||
template<bool Cond>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline typename internal::conditional<Cond,ConjugateReturnType,ConstSelfAdjointView>::type
|
|
||||||
conjugateIf() const
|
|
||||||
{
|
|
||||||
typedef typename internal::conditional<Cond,ConjugateReturnType,ConstSelfAdjointView>::type ReturnType;
|
|
||||||
return ReturnType(m_matrix.template conjugateIf<Cond>());
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef SelfAdjointView<const typename MatrixType::AdjointReturnType,TransposeMode> AdjointReturnType;
|
typedef SelfAdjointView<const typename MatrixType::AdjointReturnType,TransposeMode> AdjointReturnType;
|
||||||
/** \sa MatrixBase::adjoint() const */
|
/** \sa MatrixBase::adjoint() const */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ template<typename Decomposition, typename RhsType, typename StorageKind> class S
|
|||||||
*
|
*
|
||||||
* \brief Pseudo expression representing a solving operation
|
* \brief Pseudo expression representing a solving operation
|
||||||
*
|
*
|
||||||
* \tparam Decomposition the type of the matrix or decomposition object
|
* \tparam Decomposition the type of the matrix or decomposion object
|
||||||
* \tparam Rhstype the type of the right-hand side
|
* \tparam Rhstype the type of the right-hand side
|
||||||
*
|
*
|
||||||
* This class represents an expression of A.solve(B)
|
* This class represents an expression of A.solve(B)
|
||||||
@@ -69,8 +69,8 @@ public:
|
|||||||
: m_dec(dec), m_rhs(rhs)
|
: m_dec(dec), m_rhs(rhs)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_dec.cols(); }
|
EIGEN_DEVICE_FUNC Index rows() const { return m_dec.cols(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_rhs.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 Decomposition& dec() const { return m_dec; }
|
||||||
EIGEN_DEVICE_FUNC const RhsType& rhs() const { return m_rhs; }
|
EIGEN_DEVICE_FUNC const RhsType& rhs() const { return m_rhs; }
|
||||||
@@ -137,7 +137,7 @@ template<typename DstXprType, typename DecType, typename RhsType, typename Scala
|
|||||||
struct Assignment<DstXprType, Solve<DecType,RhsType>, internal::assign_op<Scalar,Scalar>, Dense2Dense>
|
struct Assignment<DstXprType, Solve<DecType,RhsType>, internal::assign_op<Scalar,Scalar>, Dense2Dense>
|
||||||
{
|
{
|
||||||
typedef Solve<DecType,RhsType> SrcXprType;
|
typedef Solve<DecType,RhsType> SrcXprType;
|
||||||
static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,Scalar> &)
|
static EIGEN_DEVICE_FUNC void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,Scalar> &)
|
||||||
{
|
{
|
||||||
Index dstRows = src.rows();
|
Index dstRows = src.rows();
|
||||||
Index dstCols = src.cols();
|
Index dstCols = src.cols();
|
||||||
@@ -153,7 +153,7 @@ template<typename DstXprType, typename DecType, typename RhsType, typename Scala
|
|||||||
struct Assignment<DstXprType, Solve<Transpose<const DecType>,RhsType>, internal::assign_op<Scalar,Scalar>, Dense2Dense>
|
struct Assignment<DstXprType, Solve<Transpose<const DecType>,RhsType>, internal::assign_op<Scalar,Scalar>, Dense2Dense>
|
||||||
{
|
{
|
||||||
typedef Solve<Transpose<const DecType>,RhsType> SrcXprType;
|
typedef Solve<Transpose<const DecType>,RhsType> SrcXprType;
|
||||||
static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,Scalar> &)
|
static EIGEN_DEVICE_FUNC void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,Scalar> &)
|
||||||
{
|
{
|
||||||
Index dstRows = src.rows();
|
Index dstRows = src.rows();
|
||||||
Index dstCols = src.cols();
|
Index dstCols = src.cols();
|
||||||
@@ -170,7 +170,7 @@ struct Assignment<DstXprType, Solve<CwiseUnaryOp<internal::scalar_conjugate_op<t
|
|||||||
internal::assign_op<Scalar,Scalar>, Dense2Dense>
|
internal::assign_op<Scalar,Scalar>, Dense2Dense>
|
||||||
{
|
{
|
||||||
typedef Solve<CwiseUnaryOp<internal::scalar_conjugate_op<typename DecType::Scalar>, const Transpose<const DecType> >,RhsType> SrcXprType;
|
typedef Solve<CwiseUnaryOp<internal::scalar_conjugate_op<typename DecType::Scalar>, const Transpose<const DecType> >,RhsType> SrcXprType;
|
||||||
static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,Scalar> &)
|
static EIGEN_DEVICE_FUNC void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,Scalar> &)
|
||||||
{
|
{
|
||||||
Index dstRows = src.rows();
|
Index dstRows = src.rows();
|
||||||
Index dstCols = src.cols();
|
Index dstCols = src.cols();
|
||||||
@@ -181,7 +181,7 @@ struct Assignment<DstXprType, Solve<CwiseUnaryOp<internal::scalar_conjugate_op<t
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namepsace internal
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ struct triangular_solver_selector<Lhs,Rhs,Side,Mode,NoUnrolling,1>
|
|||||||
typedef blas_traits<Lhs> LhsProductTraits;
|
typedef blas_traits<Lhs> LhsProductTraits;
|
||||||
typedef typename LhsProductTraits::ExtractType ActualLhsType;
|
typedef typename LhsProductTraits::ExtractType ActualLhsType;
|
||||||
typedef Map<Matrix<RhsScalar,Dynamic,1>, Aligned> MappedRhs;
|
typedef Map<Matrix<RhsScalar,Dynamic,1>, Aligned> MappedRhs;
|
||||||
static EIGEN_DEVICE_FUNC void run(const Lhs& lhs, Rhs& rhs)
|
static void run(const Lhs& lhs, Rhs& rhs)
|
||||||
{
|
{
|
||||||
ActualLhsType actualLhs = LhsProductTraits::extract(lhs);
|
ActualLhsType actualLhs = LhsProductTraits::extract(lhs);
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ struct triangular_solver_selector<Lhs,Rhs,Side,Mode,NoUnrolling,Dynamic>
|
|||||||
typedef blas_traits<Lhs> LhsProductTraits;
|
typedef blas_traits<Lhs> LhsProductTraits;
|
||||||
typedef typename LhsProductTraits::DirectLinearAccessType ActualLhsType;
|
typedef typename LhsProductTraits::DirectLinearAccessType ActualLhsType;
|
||||||
|
|
||||||
static EIGEN_DEVICE_FUNC void run(const Lhs& lhs, Rhs& rhs)
|
static void run(const Lhs& lhs, Rhs& rhs)
|
||||||
{
|
{
|
||||||
typename internal::add_const_on_value_type<ActualLhsType>::type actualLhs = LhsProductTraits::extract(lhs);
|
typename internal::add_const_on_value_type<ActualLhsType>::type actualLhs = LhsProductTraits::extract(lhs);
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ struct triangular_solver_unroller<Lhs,Rhs,Mode,LoopIndex,Size,false> {
|
|||||||
DiagIndex = IsLower ? LoopIndex : Size - LoopIndex - 1,
|
DiagIndex = IsLower ? LoopIndex : Size - LoopIndex - 1,
|
||||||
StartIndex = IsLower ? 0 : DiagIndex+1
|
StartIndex = IsLower ? 0 : DiagIndex+1
|
||||||
};
|
};
|
||||||
static EIGEN_DEVICE_FUNC void run(const Lhs& lhs, Rhs& rhs)
|
static void run(const Lhs& lhs, Rhs& rhs)
|
||||||
{
|
{
|
||||||
if (LoopIndex>0)
|
if (LoopIndex>0)
|
||||||
rhs.coeffRef(DiagIndex) -= lhs.row(DiagIndex).template segment<LoopIndex>(StartIndex).transpose()
|
rhs.coeffRef(DiagIndex) -= lhs.row(DiagIndex).template segment<LoopIndex>(StartIndex).transpose()
|
||||||
@@ -133,18 +133,18 @@ struct triangular_solver_unroller<Lhs,Rhs,Mode,LoopIndex,Size,false> {
|
|||||||
|
|
||||||
template<typename Lhs, typename Rhs, int Mode, int LoopIndex, int Size>
|
template<typename Lhs, typename Rhs, int Mode, int LoopIndex, int Size>
|
||||||
struct triangular_solver_unroller<Lhs,Rhs,Mode,LoopIndex,Size,true> {
|
struct triangular_solver_unroller<Lhs,Rhs,Mode,LoopIndex,Size,true> {
|
||||||
static EIGEN_DEVICE_FUNC void run(const Lhs&, Rhs&) {}
|
static void run(const Lhs&, Rhs&) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, int Mode>
|
template<typename Lhs, typename Rhs, int Mode>
|
||||||
struct triangular_solver_selector<Lhs,Rhs,OnTheLeft,Mode,CompleteUnrolling,1> {
|
struct triangular_solver_selector<Lhs,Rhs,OnTheLeft,Mode,CompleteUnrolling,1> {
|
||||||
static EIGEN_DEVICE_FUNC void run(const Lhs& lhs, Rhs& rhs)
|
static void run(const Lhs& lhs, Rhs& rhs)
|
||||||
{ triangular_solver_unroller<Lhs,Rhs,Mode,0,Rhs::SizeAtCompileTime>::run(lhs,rhs); }
|
{ triangular_solver_unroller<Lhs,Rhs,Mode,0,Rhs::SizeAtCompileTime>::run(lhs,rhs); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, int Mode>
|
template<typename Lhs, typename Rhs, int Mode>
|
||||||
struct triangular_solver_selector<Lhs,Rhs,OnTheRight,Mode,CompleteUnrolling,1> {
|
struct triangular_solver_selector<Lhs,Rhs,OnTheRight,Mode,CompleteUnrolling,1> {
|
||||||
static EIGEN_DEVICE_FUNC void run(const Lhs& lhs, Rhs& rhs)
|
static void run(const Lhs& lhs, Rhs& rhs)
|
||||||
{
|
{
|
||||||
Transpose<const Lhs> trLhs(lhs);
|
Transpose<const Lhs> trLhs(lhs);
|
||||||
Transpose<Rhs> trRhs(rhs);
|
Transpose<Rhs> trRhs(rhs);
|
||||||
@@ -168,7 +168,7 @@ EIGEN_DEVICE_FUNC void TriangularViewImpl<MatrixType,Mode,Dense>::solveInPlace(c
|
|||||||
{
|
{
|
||||||
OtherDerived& other = _other.const_cast_derived();
|
OtherDerived& other = _other.const_cast_derived();
|
||||||
eigen_assert( derived().cols() == derived().rows() && ((Side==OnTheLeft && derived().cols() == other.rows()) || (Side==OnTheRight && derived().cols() == other.cols())) );
|
eigen_assert( derived().cols() == derived().rows() && ((Side==OnTheLeft && derived().cols() == other.rows()) || (Side==OnTheRight && derived().cols() == other.cols())) );
|
||||||
eigen_assert((!(int(Mode) & int(ZeroDiag))) && bool(int(Mode) & (int(Upper) | int(Lower))));
|
eigen_assert((!(Mode & ZeroDiag)) && bool(Mode & (Upper|Lower)));
|
||||||
// If solving for a 0x0 matrix, nothing to do, simply return.
|
// If solving for a 0x0 matrix, nothing to do, simply return.
|
||||||
if (derived().cols() == 0)
|
if (derived().cols() == 0)
|
||||||
return;
|
return;
|
||||||
@@ -187,7 +187,7 @@ EIGEN_DEVICE_FUNC void TriangularViewImpl<MatrixType,Mode,Dense>::solveInPlace(c
|
|||||||
|
|
||||||
template<typename Derived, unsigned int Mode>
|
template<typename Derived, unsigned int Mode>
|
||||||
template<int Side, typename Other>
|
template<int Side, typename Other>
|
||||||
const internal::triangular_solve_retval<Side,TriangularView<Derived,Mode>,Other>
|
EIGEN_DEVICE_FUNC const internal::triangular_solve_retval<Side,TriangularView<Derived,Mode>,Other>
|
||||||
TriangularViewImpl<Derived,Mode,Dense>::solve(const MatrixBase<Other>& other) const
|
TriangularViewImpl<Derived,Mode,Dense>::solve(const MatrixBase<Other>& other) const
|
||||||
{
|
{
|
||||||
return internal::triangular_solve_retval<Side,TriangularViewType,Other>(derived(), other.derived());
|
return internal::triangular_solve_retval<Side,TriangularViewType,Other>(derived(), other.derived());
|
||||||
@@ -213,8 +213,8 @@ template<int Side, typename TriangularType, typename Rhs> struct triangular_solv
|
|||||||
: m_triangularMatrix(tri), m_rhs(rhs)
|
: m_triangularMatrix(tri), m_rhs(rhs)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
inline EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_rhs.rows(); }
|
inline Index rows() const { return m_rhs.rows(); }
|
||||||
inline EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_rhs.cols(); }
|
inline Index cols() const { return m_rhs.cols(); }
|
||||||
|
|
||||||
template<typename Dest> inline void evalTo(Dest& dst) const
|
template<typename Dest> inline void evalTo(Dest& dst) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,35 +14,8 @@ namespace Eigen {
|
|||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
struct solve_assertion {
|
|
||||||
template<bool Transpose_, typename Rhs>
|
|
||||||
static void run(const Derived& solver, const Rhs& b) { solver.template _check_solve_assertion<Transpose_>(b); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
struct solve_assertion<Transpose<Derived> >
|
|
||||||
{
|
|
||||||
typedef Transpose<Derived> type;
|
|
||||||
|
|
||||||
template<bool Transpose_, typename Rhs>
|
|
||||||
static void run(const type& transpose, const Rhs& b)
|
|
||||||
{
|
|
||||||
internal::solve_assertion<typename internal::remove_all<Derived>::type>::template run<true>(transpose.nestedExpression(), b);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Scalar, typename Derived>
|
|
||||||
struct solve_assertion<CwiseUnaryOp<Eigen::internal::scalar_conjugate_op<Scalar>, const Transpose<Derived> > >
|
|
||||||
{
|
|
||||||
typedef CwiseUnaryOp<Eigen::internal::scalar_conjugate_op<Scalar>, const Transpose<Derived> > type;
|
|
||||||
|
|
||||||
template<bool Transpose_, typename Rhs>
|
|
||||||
static void run(const type& adjoint, const Rhs& b)
|
|
||||||
{
|
|
||||||
internal::solve_assertion<typename internal::remove_all<Transpose<Derived> >::type>::template run<true>(adjoint.nestedExpression(), b);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
/** \class SolverBase
|
/** \class SolverBase
|
||||||
@@ -62,7 +35,7 @@ struct solve_assertion<CwiseUnaryOp<Eigen::internal::scalar_conjugate_op<Scalar>
|
|||||||
*
|
*
|
||||||
* \warning Currently, any other usage of transpose() and adjoint() are not supported and will produce compilation errors.
|
* \warning Currently, any other usage of transpose() and adjoint() are not supported and will produce compilation errors.
|
||||||
*
|
*
|
||||||
* \sa class PartialPivLU, class FullPivLU, class HouseholderQR, class ColPivHouseholderQR, class FullPivHouseholderQR, class CompleteOrthogonalDecomposition, class LLT, class LDLT, class SVDBase
|
* \sa class PartialPivLU, class FullPivLU
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
class SolverBase : public EigenBase<Derived>
|
class SolverBase : public EigenBase<Derived>
|
||||||
@@ -73,9 +46,6 @@ class SolverBase : public EigenBase<Derived>
|
|||||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||||
typedef Scalar CoeffReturnType;
|
typedef Scalar CoeffReturnType;
|
||||||
|
|
||||||
template<typename Derived_>
|
|
||||||
friend struct internal::solve_assertion;
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
|
RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
|
||||||
ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
|
ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
|
||||||
@@ -86,8 +56,7 @@ class SolverBase : public EigenBase<Derived>
|
|||||||
MaxSizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::MaxRowsAtCompileTime,
|
MaxSizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::MaxRowsAtCompileTime,
|
||||||
internal::traits<Derived>::MaxColsAtCompileTime>::ret),
|
internal::traits<Derived>::MaxColsAtCompileTime>::ret),
|
||||||
IsVectorAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime == 1
|
IsVectorAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime == 1
|
||||||
|| internal::traits<Derived>::MaxColsAtCompileTime == 1,
|
|| internal::traits<Derived>::MaxColsAtCompileTime == 1
|
||||||
NumDimensions = int(MaxSizeAtCompileTime) == 1 ? 0 : bool(IsVectorAtCompileTime) ? 1 : 2
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Default constructor */
|
/** Default constructor */
|
||||||
@@ -105,12 +74,12 @@ class SolverBase : public EigenBase<Derived>
|
|||||||
inline const Solve<Derived, Rhs>
|
inline const Solve<Derived, Rhs>
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
solve(const MatrixBase<Rhs>& b) const
|
||||||
{
|
{
|
||||||
internal::solve_assertion<typename internal::remove_all<Derived>::type>::template run<false>(derived(), b);
|
eigen_assert(derived().rows()==b.rows() && "solve(): invalid number of rows of the right hand side matrix b");
|
||||||
return Solve<Derived, Rhs>(derived(), b.derived());
|
return Solve<Derived, Rhs>(derived(), b.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \internal the return type of transpose() */
|
/** \internal the return type of transpose() */
|
||||||
typedef Transpose<const Derived> ConstTransposeReturnType;
|
typedef typename internal::add_const<Transpose<const Derived> >::type ConstTransposeReturnType;
|
||||||
/** \returns an expression of the transposed of the factored matrix.
|
/** \returns an expression of the transposed of the factored matrix.
|
||||||
*
|
*
|
||||||
* A typical usage is to solve for the transposed problem A^T x = b:
|
* A typical usage is to solve for the transposed problem A^T x = b:
|
||||||
@@ -118,16 +87,16 @@ class SolverBase : public EigenBase<Derived>
|
|||||||
*
|
*
|
||||||
* \sa adjoint(), solve()
|
* \sa adjoint(), solve()
|
||||||
*/
|
*/
|
||||||
inline const ConstTransposeReturnType transpose() const
|
inline ConstTransposeReturnType transpose() const
|
||||||
{
|
{
|
||||||
return ConstTransposeReturnType(derived());
|
return ConstTransposeReturnType(derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \internal the return type of adjoint() */
|
/** \internal the return type of adjoint() */
|
||||||
typedef typename internal::conditional<NumTraits<Scalar>::IsComplex,
|
typedef typename internal::conditional<NumTraits<Scalar>::IsComplex,
|
||||||
CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, const ConstTransposeReturnType>,
|
CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, ConstTransposeReturnType>,
|
||||||
const ConstTransposeReturnType
|
ConstTransposeReturnType
|
||||||
>::type AdjointReturnType;
|
>::type AdjointReturnType;
|
||||||
/** \returns an expression of the adjoint of the factored matrix
|
/** \returns an expression of the adjoint of the factored matrix
|
||||||
*
|
*
|
||||||
* A typical usage is to solve for the adjoint problem A' x = b:
|
* A typical usage is to solve for the adjoint problem A' x = b:
|
||||||
@@ -137,19 +106,12 @@ class SolverBase : public EigenBase<Derived>
|
|||||||
*
|
*
|
||||||
* \sa transpose(), solve()
|
* \sa transpose(), solve()
|
||||||
*/
|
*/
|
||||||
inline const AdjointReturnType adjoint() const
|
inline AdjointReturnType adjoint() const
|
||||||
{
|
{
|
||||||
return AdjointReturnType(derived().transpose());
|
return AdjointReturnType(derived().transpose());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
template<bool Transpose_, typename Rhs>
|
|
||||||
void _check_solve_assertion(const Rhs& b) const {
|
|
||||||
EIGEN_ONLY_USED_FOR_DEBUG(b);
|
|
||||||
eigen_assert(derived().m_isInitialized && "Solver is not initialized.");
|
|
||||||
eigen_assert((Transpose_?derived().cols():derived().rows())==b.rows() && "SolverBase::solve(): invalid number of rows of the right hand side matrix b");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|||||||
@@ -50,71 +50,6 @@ inline void stable_norm_kernel(const ExpressionType& bl, Scalar& ssq, Scalar& sc
|
|||||||
ssq += (bl*invScale).squaredNorm();
|
ssq += (bl*invScale).squaredNorm();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename VectorType, typename RealScalar>
|
|
||||||
void stable_norm_impl_inner_step(const VectorType &vec, RealScalar& ssq, RealScalar& scale, RealScalar& invScale)
|
|
||||||
{
|
|
||||||
typedef typename VectorType::Scalar Scalar;
|
|
||||||
const Index blockSize = 4096;
|
|
||||||
|
|
||||||
typedef typename internal::nested_eval<VectorType,2>::type VectorTypeCopy;
|
|
||||||
typedef typename internal::remove_all<VectorTypeCopy>::type VectorTypeCopyClean;
|
|
||||||
const VectorTypeCopy copy(vec);
|
|
||||||
|
|
||||||
enum {
|
|
||||||
CanAlign = ( (int(VectorTypeCopyClean::Flags)&DirectAccessBit)
|
|
||||||
|| (int(internal::evaluator<VectorTypeCopyClean>::Alignment)>0) // FIXME Alignment)>0 might not be enough
|
|
||||||
) && (blockSize*sizeof(Scalar)*2<EIGEN_STACK_ALLOCATION_LIMIT)
|
|
||||||
&& (EIGEN_MAX_STATIC_ALIGN_BYTES>0) // if we cannot allocate on the stack, then let's not bother about this optimization
|
|
||||||
};
|
|
||||||
typedef typename internal::conditional<CanAlign, Ref<const Matrix<Scalar,Dynamic,1,0,blockSize,1>, internal::evaluator<VectorTypeCopyClean>::Alignment>,
|
|
||||||
typename VectorTypeCopyClean::ConstSegmentReturnType>::type SegmentWrapper;
|
|
||||||
Index n = vec.size();
|
|
||||||
|
|
||||||
Index bi = internal::first_default_aligned(copy);
|
|
||||||
if (bi>0)
|
|
||||||
internal::stable_norm_kernel(copy.head(bi), ssq, scale, invScale);
|
|
||||||
for (; bi<n; bi+=blockSize)
|
|
||||||
internal::stable_norm_kernel(SegmentWrapper(copy.segment(bi,numext::mini(blockSize, n - bi))), ssq, scale, invScale);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename VectorType>
|
|
||||||
typename VectorType::RealScalar
|
|
||||||
stable_norm_impl(const VectorType &vec, typename enable_if<VectorType::IsVectorAtCompileTime>::type* = 0 )
|
|
||||||
{
|
|
||||||
using std::sqrt;
|
|
||||||
using std::abs;
|
|
||||||
|
|
||||||
Index n = vec.size();
|
|
||||||
|
|
||||||
if(n==1)
|
|
||||||
return abs(vec.coeff(0));
|
|
||||||
|
|
||||||
typedef typename VectorType::RealScalar RealScalar;
|
|
||||||
RealScalar scale(0);
|
|
||||||
RealScalar invScale(1);
|
|
||||||
RealScalar ssq(0); // sum of squares
|
|
||||||
|
|
||||||
stable_norm_impl_inner_step(vec, ssq, scale, invScale);
|
|
||||||
|
|
||||||
return scale * sqrt(ssq);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename MatrixType>
|
|
||||||
typename MatrixType::RealScalar
|
|
||||||
stable_norm_impl(const MatrixType &mat, typename enable_if<!MatrixType::IsVectorAtCompileTime>::type* = 0 )
|
|
||||||
{
|
|
||||||
using std::sqrt;
|
|
||||||
|
|
||||||
typedef typename MatrixType::RealScalar RealScalar;
|
|
||||||
RealScalar scale(0);
|
|
||||||
RealScalar invScale(1);
|
|
||||||
RealScalar ssq(0); // sum of squares
|
|
||||||
|
|
||||||
for(Index j=0; j<mat.outerSize(); ++j)
|
|
||||||
stable_norm_impl_inner_step(mat.innerVector(j), ssq, scale, invScale);
|
|
||||||
return scale * sqrt(ssq);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline typename NumTraits<typename traits<Derived>::Scalar>::Real
|
inline typename NumTraits<typename traits<Derived>::Scalar>::Real
|
||||||
blueNorm_impl(const EigenBase<Derived>& _vec)
|
blueNorm_impl(const EigenBase<Derived>& _vec)
|
||||||
@@ -123,43 +58,52 @@ blueNorm_impl(const EigenBase<Derived>& _vec)
|
|||||||
using std::pow;
|
using std::pow;
|
||||||
using std::sqrt;
|
using std::sqrt;
|
||||||
using std::abs;
|
using std::abs;
|
||||||
|
|
||||||
// This program calculates the machine-dependent constants
|
|
||||||
// bl, b2, slm, s2m, relerr overfl
|
|
||||||
// from the "basic" machine-dependent numbers
|
|
||||||
// nbig, ibeta, it, iemin, iemax, rbig.
|
|
||||||
// The following define the basic machine-dependent constants.
|
|
||||||
// For portability, the PORT subprograms "ilmaeh" and "rlmach"
|
|
||||||
// are used. For any specific computer, each of the assignment
|
|
||||||
// statements can be replaced
|
|
||||||
static const int ibeta = std::numeric_limits<RealScalar>::radix; // base for floating-point numbers
|
|
||||||
static const int it = NumTraits<RealScalar>::digits(); // number of base-beta digits in mantissa
|
|
||||||
static const int iemin = NumTraits<RealScalar>::min_exponent(); // minimum exponent
|
|
||||||
static const int iemax = NumTraits<RealScalar>::max_exponent(); // maximum exponent
|
|
||||||
static const RealScalar rbig = NumTraits<RealScalar>::highest(); // largest floating-point number
|
|
||||||
static const RealScalar b1 = RealScalar(pow(RealScalar(ibeta),RealScalar(-((1-iemin)/2)))); // lower boundary of midrange
|
|
||||||
static const RealScalar b2 = RealScalar(pow(RealScalar(ibeta),RealScalar((iemax + 1 - it)/2))); // upper boundary of midrange
|
|
||||||
static const RealScalar s1m = RealScalar(pow(RealScalar(ibeta),RealScalar((2-iemin)/2))); // scaling factor for lower range
|
|
||||||
static const RealScalar s2m = RealScalar(pow(RealScalar(ibeta),RealScalar(- ((iemax+it)/2)))); // scaling factor for upper range
|
|
||||||
static const RealScalar eps = RealScalar(pow(double(ibeta), 1-it));
|
|
||||||
static const RealScalar relerr = sqrt(eps); // tolerance for neglecting asml
|
|
||||||
|
|
||||||
const Derived& vec(_vec.derived());
|
const Derived& vec(_vec.derived());
|
||||||
|
static bool initialized = false;
|
||||||
|
static RealScalar b1, b2, s1m, s2m, rbig, relerr;
|
||||||
|
if(!initialized)
|
||||||
|
{
|
||||||
|
int ibeta, it, iemin, iemax, iexp;
|
||||||
|
RealScalar eps;
|
||||||
|
// This program calculates the machine-dependent constants
|
||||||
|
// bl, b2, slm, s2m, relerr overfl
|
||||||
|
// from the "basic" machine-dependent numbers
|
||||||
|
// nbig, ibeta, it, iemin, iemax, rbig.
|
||||||
|
// The following define the basic machine-dependent constants.
|
||||||
|
// For portability, the PORT subprograms "ilmaeh" and "rlmach"
|
||||||
|
// are used. For any specific computer, each of the assignment
|
||||||
|
// statements can be replaced
|
||||||
|
ibeta = std::numeric_limits<RealScalar>::radix; // base for floating-point numbers
|
||||||
|
it = std::numeric_limits<RealScalar>::digits; // number of base-beta digits in mantissa
|
||||||
|
iemin = std::numeric_limits<RealScalar>::min_exponent; // minimum exponent
|
||||||
|
iemax = std::numeric_limits<RealScalar>::max_exponent; // maximum exponent
|
||||||
|
rbig = (std::numeric_limits<RealScalar>::max)(); // largest floating-point number
|
||||||
|
|
||||||
|
iexp = -((1-iemin)/2);
|
||||||
|
b1 = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // lower boundary of midrange
|
||||||
|
iexp = (iemax + 1 - it)/2;
|
||||||
|
b2 = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // upper boundary of midrange
|
||||||
|
|
||||||
|
iexp = (2-iemin)/2;
|
||||||
|
s1m = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for lower range
|
||||||
|
iexp = - ((iemax+it)/2);
|
||||||
|
s2m = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for upper range
|
||||||
|
|
||||||
|
eps = RealScalar(pow(double(ibeta), 1-it));
|
||||||
|
relerr = sqrt(eps); // tolerance for neglecting asml
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
Index n = vec.size();
|
Index n = vec.size();
|
||||||
RealScalar ab2 = b2 / RealScalar(n);
|
RealScalar ab2 = b2 / RealScalar(n);
|
||||||
RealScalar asml = RealScalar(0);
|
RealScalar asml = RealScalar(0);
|
||||||
RealScalar amed = RealScalar(0);
|
RealScalar amed = RealScalar(0);
|
||||||
RealScalar abig = RealScalar(0);
|
RealScalar abig = RealScalar(0);
|
||||||
|
for(typename Derived::InnerIterator it(vec, 0); it; ++it)
|
||||||
for(Index j=0; j<vec.outerSize(); ++j)
|
|
||||||
{
|
{
|
||||||
for(typename Derived::InnerIterator iter(vec, j); iter; ++iter)
|
RealScalar ax = abs(it.value());
|
||||||
{
|
if(ax > ab2) abig += numext::abs2(ax*s2m);
|
||||||
RealScalar ax = abs(iter.value());
|
else if(ax < b1) asml += numext::abs2(ax*s1m);
|
||||||
if(ax > ab2) abig += numext::abs2(ax*s2m);
|
else amed += numext::abs2(ax);
|
||||||
else if(ax < b1) asml += numext::abs2(ax*s1m);
|
|
||||||
else amed += numext::abs2(ax);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(amed!=amed)
|
if(amed!=amed)
|
||||||
return amed; // we got a NaN
|
return amed; // we got a NaN
|
||||||
@@ -212,7 +156,36 @@ template<typename Derived>
|
|||||||
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
|
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
|
||||||
MatrixBase<Derived>::stableNorm() const
|
MatrixBase<Derived>::stableNorm() const
|
||||||
{
|
{
|
||||||
return internal::stable_norm_impl(derived());
|
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;
|
||||||
|
const DerivedCopy copy(derived());
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CanAlign = ( (int(DerivedCopyClean::Flags)&DirectAccessBit)
|
||||||
|
|| (int(internal::evaluator<DerivedCopyClean>::Alignment)>0) // FIXME Alignment)>0 might not be enough
|
||||||
|
) && (blockSize*sizeof(Scalar)*2<EIGEN_STACK_ALLOCATION_LIMIT)
|
||||||
|
&& (EIGEN_MAX_STATIC_ALIGN_BYTES>0) // if we cannot allocate on the stack, then let's not bother about this optimization
|
||||||
|
};
|
||||||
|
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();
|
||||||
|
|
||||||
|
if(n==1)
|
||||||
|
return abs(this->coeff(0));
|
||||||
|
|
||||||
|
Index bi = internal::first_default_aligned(copy);
|
||||||
|
if (bi>0)
|
||||||
|
internal::stable_norm_kernel(copy.head(bi), ssq, scale, invScale);
|
||||||
|
for (; bi<n; bi+=blockSize)
|
||||||
|
internal::stable_norm_kernel(SegmentWrapper(copy.segment(bi,numext::mini(blockSize, n - bi))), ssq, scale, invScale);
|
||||||
|
return scale * sqrt(ssq);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the \em l2 norm of \c *this using the Blue's algorithm.
|
/** \returns the \em l2 norm of \c *this using the Blue's algorithm.
|
||||||
@@ -240,10 +213,7 @@ template<typename Derived>
|
|||||||
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
|
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
|
||||||
MatrixBase<Derived>::hypotNorm() const
|
MatrixBase<Derived>::hypotNorm() const
|
||||||
{
|
{
|
||||||
if(size()==1)
|
return this->cwiseAbs().redux(internal::scalar_hypot_op<RealScalar>());
|
||||||
return numext::abs(coeff(0,0));
|
|
||||||
else
|
|
||||||
return this->cwiseAbs().redux(internal::scalar_hypot_op<RealScalar>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|||||||
@@ -1,463 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2018 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_STLITERATORS_H
|
|
||||||
#define EIGEN_STLITERATORS_H
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template<typename IteratorType>
|
|
||||||
struct indexed_based_stl_iterator_traits;
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
class indexed_based_stl_iterator_base
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
typedef indexed_based_stl_iterator_traits<Derived> traits;
|
|
||||||
typedef typename traits::XprType XprType;
|
|
||||||
typedef indexed_based_stl_iterator_base<typename traits::non_const_iterator> non_const_iterator;
|
|
||||||
typedef indexed_based_stl_iterator_base<typename traits::const_iterator> const_iterator;
|
|
||||||
typedef typename internal::conditional<internal::is_const<XprType>::value,non_const_iterator,const_iterator>::type other_iterator;
|
|
||||||
// NOTE: in C++03 we cannot declare friend classes through typedefs because we need to write friend class:
|
|
||||||
friend class indexed_based_stl_iterator_base<typename traits::const_iterator>;
|
|
||||||
friend class indexed_based_stl_iterator_base<typename traits::non_const_iterator>;
|
|
||||||
public:
|
|
||||||
typedef Index difference_type;
|
|
||||||
typedef std::random_access_iterator_tag iterator_category;
|
|
||||||
|
|
||||||
indexed_based_stl_iterator_base() EIGEN_NO_THROW : mp_xpr(0), m_index(0) {}
|
|
||||||
indexed_based_stl_iterator_base(XprType& xpr, Index index) EIGEN_NO_THROW : mp_xpr(&xpr), m_index(index) {}
|
|
||||||
|
|
||||||
indexed_based_stl_iterator_base(const non_const_iterator& other) EIGEN_NO_THROW
|
|
||||||
: mp_xpr(other.mp_xpr), m_index(other.m_index)
|
|
||||||
{}
|
|
||||||
|
|
||||||
indexed_based_stl_iterator_base& operator=(const non_const_iterator& other)
|
|
||||||
{
|
|
||||||
mp_xpr = other.mp_xpr;
|
|
||||||
m_index = other.m_index;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Derived& operator++() { ++m_index; return derived(); }
|
|
||||||
Derived& operator--() { --m_index; return derived(); }
|
|
||||||
|
|
||||||
Derived operator++(int) { Derived prev(derived()); operator++(); return prev;}
|
|
||||||
Derived operator--(int) { Derived prev(derived()); operator--(); return prev;}
|
|
||||||
|
|
||||||
friend Derived operator+(const indexed_based_stl_iterator_base& a, Index b) { Derived ret(a.derived()); ret += b; return ret; }
|
|
||||||
friend Derived operator-(const indexed_based_stl_iterator_base& a, Index b) { Derived ret(a.derived()); ret -= b; return ret; }
|
|
||||||
friend Derived operator+(Index a, const indexed_based_stl_iterator_base& b) { Derived ret(b.derived()); ret += a; return ret; }
|
|
||||||
friend Derived operator-(Index a, const indexed_based_stl_iterator_base& b) { Derived ret(b.derived()); ret -= a; return ret; }
|
|
||||||
|
|
||||||
Derived& operator+=(Index b) { m_index += b; return derived(); }
|
|
||||||
Derived& operator-=(Index b) { m_index -= b; return derived(); }
|
|
||||||
|
|
||||||
difference_type operator-(const indexed_based_stl_iterator_base& other) const
|
|
||||||
{
|
|
||||||
eigen_assert(mp_xpr == other.mp_xpr);
|
|
||||||
return m_index - other.m_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
difference_type operator-(const other_iterator& other) const
|
|
||||||
{
|
|
||||||
eigen_assert(mp_xpr == other.mp_xpr);
|
|
||||||
return m_index - other.m_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index == other.m_index; }
|
|
||||||
bool operator!=(const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index != other.m_index; }
|
|
||||||
bool operator< (const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index < other.m_index; }
|
|
||||||
bool operator<=(const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index <= other.m_index; }
|
|
||||||
bool operator> (const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index > other.m_index; }
|
|
||||||
bool operator>=(const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index >= other.m_index; }
|
|
||||||
|
|
||||||
bool operator==(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index == other.m_index; }
|
|
||||||
bool operator!=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index != other.m_index; }
|
|
||||||
bool operator< (const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index < other.m_index; }
|
|
||||||
bool operator<=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index <= other.m_index; }
|
|
||||||
bool operator> (const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index > other.m_index; }
|
|
||||||
bool operator>=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index >= other.m_index; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
Derived& derived() { return static_cast<Derived&>(*this); }
|
|
||||||
const Derived& derived() const { return static_cast<const Derived&>(*this); }
|
|
||||||
|
|
||||||
XprType *mp_xpr;
|
|
||||||
Index m_index;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
class indexed_based_stl_reverse_iterator_base
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
typedef indexed_based_stl_iterator_traits<Derived> traits;
|
|
||||||
typedef typename traits::XprType XprType;
|
|
||||||
typedef indexed_based_stl_reverse_iterator_base<typename traits::non_const_iterator> non_const_iterator;
|
|
||||||
typedef indexed_based_stl_reverse_iterator_base<typename traits::const_iterator> const_iterator;
|
|
||||||
typedef typename internal::conditional<internal::is_const<XprType>::value,non_const_iterator,const_iterator>::type other_iterator;
|
|
||||||
// NOTE: in C++03 we cannot declare friend classes through typedefs because we need to write friend class:
|
|
||||||
friend class indexed_based_stl_reverse_iterator_base<typename traits::const_iterator>;
|
|
||||||
friend class indexed_based_stl_reverse_iterator_base<typename traits::non_const_iterator>;
|
|
||||||
public:
|
|
||||||
typedef Index difference_type;
|
|
||||||
typedef std::random_access_iterator_tag iterator_category;
|
|
||||||
|
|
||||||
indexed_based_stl_reverse_iterator_base() : mp_xpr(0), m_index(0) {}
|
|
||||||
indexed_based_stl_reverse_iterator_base(XprType& xpr, Index index) : mp_xpr(&xpr), m_index(index) {}
|
|
||||||
|
|
||||||
indexed_based_stl_reverse_iterator_base(const non_const_iterator& other)
|
|
||||||
: mp_xpr(other.mp_xpr), m_index(other.m_index)
|
|
||||||
{}
|
|
||||||
|
|
||||||
indexed_based_stl_reverse_iterator_base& operator=(const non_const_iterator& other)
|
|
||||||
{
|
|
||||||
mp_xpr = other.mp_xpr;
|
|
||||||
m_index = other.m_index;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Derived& operator++() { --m_index; return derived(); }
|
|
||||||
Derived& operator--() { ++m_index; return derived(); }
|
|
||||||
|
|
||||||
Derived operator++(int) { Derived prev(derived()); operator++(); return prev;}
|
|
||||||
Derived operator--(int) { Derived prev(derived()); operator--(); return prev;}
|
|
||||||
|
|
||||||
friend Derived operator+(const indexed_based_stl_reverse_iterator_base& a, Index b) { Derived ret(a.derived()); ret += b; return ret; }
|
|
||||||
friend Derived operator-(const indexed_based_stl_reverse_iterator_base& a, Index b) { Derived ret(a.derived()); ret -= b; return ret; }
|
|
||||||
friend Derived operator+(Index a, const indexed_based_stl_reverse_iterator_base& b) { Derived ret(b.derived()); ret += a; return ret; }
|
|
||||||
friend Derived operator-(Index a, const indexed_based_stl_reverse_iterator_base& b) { Derived ret(b.derived()); ret -= a; return ret; }
|
|
||||||
|
|
||||||
Derived& operator+=(Index b) { m_index -= b; return derived(); }
|
|
||||||
Derived& operator-=(Index b) { m_index += b; return derived(); }
|
|
||||||
|
|
||||||
difference_type operator-(const indexed_based_stl_reverse_iterator_base& other) const
|
|
||||||
{
|
|
||||||
eigen_assert(mp_xpr == other.mp_xpr);
|
|
||||||
return other.m_index - m_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
difference_type operator-(const other_iterator& other) const
|
|
||||||
{
|
|
||||||
eigen_assert(mp_xpr == other.mp_xpr);
|
|
||||||
return other.m_index - m_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index == other.m_index; }
|
|
||||||
bool operator!=(const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index != other.m_index; }
|
|
||||||
bool operator< (const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index > other.m_index; }
|
|
||||||
bool operator<=(const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index >= other.m_index; }
|
|
||||||
bool operator> (const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index < other.m_index; }
|
|
||||||
bool operator>=(const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index <= other.m_index; }
|
|
||||||
|
|
||||||
bool operator==(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index == other.m_index; }
|
|
||||||
bool operator!=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index != other.m_index; }
|
|
||||||
bool operator< (const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index > other.m_index; }
|
|
||||||
bool operator<=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index >= other.m_index; }
|
|
||||||
bool operator> (const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index < other.m_index; }
|
|
||||||
bool operator>=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index <= other.m_index; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
Derived& derived() { return static_cast<Derived&>(*this); }
|
|
||||||
const Derived& derived() const { return static_cast<const Derived&>(*this); }
|
|
||||||
|
|
||||||
XprType *mp_xpr;
|
|
||||||
Index m_index;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename XprType>
|
|
||||||
class pointer_based_stl_iterator
|
|
||||||
{
|
|
||||||
enum { is_lvalue = internal::is_lvalue<XprType>::value };
|
|
||||||
typedef pointer_based_stl_iterator<typename internal::remove_const<XprType>::type> non_const_iterator;
|
|
||||||
typedef pointer_based_stl_iterator<typename internal::add_const<XprType>::type> const_iterator;
|
|
||||||
typedef typename internal::conditional<internal::is_const<XprType>::value,non_const_iterator,const_iterator>::type other_iterator;
|
|
||||||
// NOTE: in C++03 we cannot declare friend classes through typedefs because we need to write friend class:
|
|
||||||
friend class pointer_based_stl_iterator<typename internal::add_const<XprType>::type>;
|
|
||||||
friend class pointer_based_stl_iterator<typename internal::remove_const<XprType>::type>;
|
|
||||||
public:
|
|
||||||
typedef Index difference_type;
|
|
||||||
typedef typename XprType::Scalar value_type;
|
|
||||||
typedef std::random_access_iterator_tag iterator_category;
|
|
||||||
typedef typename internal::conditional<bool(is_lvalue), value_type*, const value_type*>::type pointer;
|
|
||||||
typedef typename internal::conditional<bool(is_lvalue), value_type&, const value_type&>::type reference;
|
|
||||||
|
|
||||||
|
|
||||||
pointer_based_stl_iterator() EIGEN_NO_THROW : m_ptr(0) {}
|
|
||||||
pointer_based_stl_iterator(XprType& xpr, Index index) EIGEN_NO_THROW : m_incr(xpr.innerStride())
|
|
||||||
{
|
|
||||||
m_ptr = xpr.data() + index * m_incr.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
pointer_based_stl_iterator(const non_const_iterator& other) EIGEN_NO_THROW
|
|
||||||
: m_ptr(other.m_ptr), m_incr(other.m_incr)
|
|
||||||
{}
|
|
||||||
|
|
||||||
pointer_based_stl_iterator& operator=(const non_const_iterator& other) EIGEN_NO_THROW
|
|
||||||
{
|
|
||||||
m_ptr = other.m_ptr;
|
|
||||||
m_incr.setValue(other.m_incr);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
reference operator*() const { return *m_ptr; }
|
|
||||||
reference operator[](Index i) const { return *(m_ptr+i*m_incr.value()); }
|
|
||||||
pointer operator->() const { return m_ptr; }
|
|
||||||
|
|
||||||
pointer_based_stl_iterator& operator++() { m_ptr += m_incr.value(); return *this; }
|
|
||||||
pointer_based_stl_iterator& operator--() { m_ptr -= m_incr.value(); return *this; }
|
|
||||||
|
|
||||||
pointer_based_stl_iterator operator++(int) { pointer_based_stl_iterator prev(*this); operator++(); return prev;}
|
|
||||||
pointer_based_stl_iterator operator--(int) { pointer_based_stl_iterator prev(*this); operator--(); return prev;}
|
|
||||||
|
|
||||||
friend pointer_based_stl_iterator operator+(const pointer_based_stl_iterator& a, Index b) { pointer_based_stl_iterator ret(a); ret += b; return ret; }
|
|
||||||
friend pointer_based_stl_iterator operator-(const pointer_based_stl_iterator& a, Index b) { pointer_based_stl_iterator ret(a); ret -= b; return ret; }
|
|
||||||
friend pointer_based_stl_iterator operator+(Index a, const pointer_based_stl_iterator& b) { pointer_based_stl_iterator ret(b); ret += a; return ret; }
|
|
||||||
friend pointer_based_stl_iterator operator-(Index a, const pointer_based_stl_iterator& b) { pointer_based_stl_iterator ret(b); ret -= a; return ret; }
|
|
||||||
|
|
||||||
pointer_based_stl_iterator& operator+=(Index b) { m_ptr += b*m_incr.value(); return *this; }
|
|
||||||
pointer_based_stl_iterator& operator-=(Index b) { m_ptr -= b*m_incr.value(); return *this; }
|
|
||||||
|
|
||||||
difference_type operator-(const pointer_based_stl_iterator& other) const {
|
|
||||||
return (m_ptr - other.m_ptr)/m_incr.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
difference_type operator-(const other_iterator& other) const {
|
|
||||||
return (m_ptr - other.m_ptr)/m_incr.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const pointer_based_stl_iterator& other) const { return m_ptr == other.m_ptr; }
|
|
||||||
bool operator!=(const pointer_based_stl_iterator& other) const { return m_ptr != other.m_ptr; }
|
|
||||||
bool operator< (const pointer_based_stl_iterator& other) const { return m_ptr < other.m_ptr; }
|
|
||||||
bool operator<=(const pointer_based_stl_iterator& other) const { return m_ptr <= other.m_ptr; }
|
|
||||||
bool operator> (const pointer_based_stl_iterator& other) const { return m_ptr > other.m_ptr; }
|
|
||||||
bool operator>=(const pointer_based_stl_iterator& other) const { return m_ptr >= other.m_ptr; }
|
|
||||||
|
|
||||||
bool operator==(const other_iterator& other) const { return m_ptr == other.m_ptr; }
|
|
||||||
bool operator!=(const other_iterator& other) const { return m_ptr != other.m_ptr; }
|
|
||||||
bool operator< (const other_iterator& other) const { return m_ptr < other.m_ptr; }
|
|
||||||
bool operator<=(const other_iterator& other) const { return m_ptr <= other.m_ptr; }
|
|
||||||
bool operator> (const other_iterator& other) const { return m_ptr > other.m_ptr; }
|
|
||||||
bool operator>=(const other_iterator& other) const { return m_ptr >= other.m_ptr; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
pointer m_ptr;
|
|
||||||
internal::variable_if_dynamic<Index, XprType::InnerStrideAtCompileTime> m_incr;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename _XprType>
|
|
||||||
struct indexed_based_stl_iterator_traits<generic_randaccess_stl_iterator<_XprType> >
|
|
||||||
{
|
|
||||||
typedef _XprType XprType;
|
|
||||||
typedef generic_randaccess_stl_iterator<typename internal::remove_const<XprType>::type> non_const_iterator;
|
|
||||||
typedef generic_randaccess_stl_iterator<typename internal::add_const<XprType>::type> const_iterator;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename XprType>
|
|
||||||
class generic_randaccess_stl_iterator : public indexed_based_stl_iterator_base<generic_randaccess_stl_iterator<XprType> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef typename XprType::Scalar value_type;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
enum {
|
|
||||||
has_direct_access = (internal::traits<XprType>::Flags & DirectAccessBit) ? 1 : 0,
|
|
||||||
is_lvalue = internal::is_lvalue<XprType>::value
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef indexed_based_stl_iterator_base<generic_randaccess_stl_iterator> Base;
|
|
||||||
using Base::m_index;
|
|
||||||
using Base::mp_xpr;
|
|
||||||
|
|
||||||
// TODO currently const Transpose/Reshape expressions never returns const references,
|
|
||||||
// so lets return by value too.
|
|
||||||
//typedef typename internal::conditional<bool(has_direct_access), const value_type&, const value_type>::type read_only_ref_t;
|
|
||||||
typedef const value_type read_only_ref_t;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef typename internal::conditional<bool(is_lvalue), value_type *, const value_type *>::type pointer;
|
|
||||||
typedef typename internal::conditional<bool(is_lvalue), value_type&, read_only_ref_t>::type reference;
|
|
||||||
|
|
||||||
generic_randaccess_stl_iterator() : Base() {}
|
|
||||||
generic_randaccess_stl_iterator(XprType& xpr, Index index) : Base(xpr,index) {}
|
|
||||||
generic_randaccess_stl_iterator(const typename Base::non_const_iterator& other) : Base(other) {}
|
|
||||||
using Base::operator=;
|
|
||||||
|
|
||||||
reference operator*() const { return (*mp_xpr)(m_index); }
|
|
||||||
reference operator[](Index i) const { return (*mp_xpr)(m_index+i); }
|
|
||||||
pointer operator->() const { return &((*mp_xpr)(m_index)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename _XprType, DirectionType Direction>
|
|
||||||
struct indexed_based_stl_iterator_traits<subvector_stl_iterator<_XprType,Direction> >
|
|
||||||
{
|
|
||||||
typedef _XprType XprType;
|
|
||||||
typedef subvector_stl_iterator<typename internal::remove_const<XprType>::type, Direction> non_const_iterator;
|
|
||||||
typedef subvector_stl_iterator<typename internal::add_const<XprType>::type, Direction> const_iterator;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename XprType, DirectionType Direction>
|
|
||||||
class subvector_stl_iterator : public indexed_based_stl_iterator_base<subvector_stl_iterator<XprType,Direction> >
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
|
|
||||||
enum { is_lvalue = internal::is_lvalue<XprType>::value };
|
|
||||||
|
|
||||||
typedef indexed_based_stl_iterator_base<subvector_stl_iterator> Base;
|
|
||||||
using Base::m_index;
|
|
||||||
using Base::mp_xpr;
|
|
||||||
|
|
||||||
typedef typename internal::conditional<Direction==Vertical,typename XprType::ColXpr,typename XprType::RowXpr>::type SubVectorType;
|
|
||||||
typedef typename internal::conditional<Direction==Vertical,typename XprType::ConstColXpr,typename XprType::ConstRowXpr>::type ConstSubVectorType;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef typename internal::conditional<bool(is_lvalue), SubVectorType, ConstSubVectorType>::type reference;
|
|
||||||
typedef typename reference::PlainObject value_type;
|
|
||||||
|
|
||||||
private:
|
|
||||||
class subvector_stl_iterator_ptr
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
subvector_stl_iterator_ptr(const reference &subvector) : m_subvector(subvector) {}
|
|
||||||
reference* operator->() { return &m_subvector; }
|
|
||||||
private:
|
|
||||||
reference m_subvector;
|
|
||||||
};
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef subvector_stl_iterator_ptr pointer;
|
|
||||||
|
|
||||||
subvector_stl_iterator() : Base() {}
|
|
||||||
subvector_stl_iterator(XprType& xpr, Index index) : Base(xpr,index) {}
|
|
||||||
|
|
||||||
reference operator*() const { return (*mp_xpr).template subVector<Direction>(m_index); }
|
|
||||||
reference operator[](Index i) const { return (*mp_xpr).template subVector<Direction>(m_index+i); }
|
|
||||||
pointer operator->() const { return (*mp_xpr).template subVector<Direction>(m_index); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename _XprType, DirectionType Direction>
|
|
||||||
struct indexed_based_stl_iterator_traits<subvector_stl_reverse_iterator<_XprType,Direction> >
|
|
||||||
{
|
|
||||||
typedef _XprType XprType;
|
|
||||||
typedef subvector_stl_reverse_iterator<typename internal::remove_const<XprType>::type, Direction> non_const_iterator;
|
|
||||||
typedef subvector_stl_reverse_iterator<typename internal::add_const<XprType>::type, Direction> const_iterator;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename XprType, DirectionType Direction>
|
|
||||||
class subvector_stl_reverse_iterator : public indexed_based_stl_reverse_iterator_base<subvector_stl_reverse_iterator<XprType,Direction> >
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
|
|
||||||
enum { is_lvalue = internal::is_lvalue<XprType>::value };
|
|
||||||
|
|
||||||
typedef indexed_based_stl_reverse_iterator_base<subvector_stl_reverse_iterator> Base;
|
|
||||||
using Base::m_index;
|
|
||||||
using Base::mp_xpr;
|
|
||||||
|
|
||||||
typedef typename internal::conditional<Direction==Vertical,typename XprType::ColXpr,typename XprType::RowXpr>::type SubVectorType;
|
|
||||||
typedef typename internal::conditional<Direction==Vertical,typename XprType::ConstColXpr,typename XprType::ConstRowXpr>::type ConstSubVectorType;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef typename internal::conditional<bool(is_lvalue), SubVectorType, ConstSubVectorType>::type reference;
|
|
||||||
typedef typename reference::PlainObject value_type;
|
|
||||||
|
|
||||||
private:
|
|
||||||
class subvector_stl_reverse_iterator_ptr
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
subvector_stl_reverse_iterator_ptr(const reference &subvector) : m_subvector(subvector) {}
|
|
||||||
reference* operator->() { return &m_subvector; }
|
|
||||||
private:
|
|
||||||
reference m_subvector;
|
|
||||||
};
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef subvector_stl_reverse_iterator_ptr pointer;
|
|
||||||
|
|
||||||
subvector_stl_reverse_iterator() : Base() {}
|
|
||||||
subvector_stl_reverse_iterator(XprType& xpr, Index index) : Base(xpr,index) {}
|
|
||||||
|
|
||||||
reference operator*() const { return (*mp_xpr).template subVector<Direction>(m_index); }
|
|
||||||
reference operator[](Index i) const { return (*mp_xpr).template subVector<Direction>(m_index+i); }
|
|
||||||
pointer operator->() const { return (*mp_xpr).template subVector<Direction>(m_index); }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
|
|
||||||
/** returns an iterator to the first element of the 1D vector or array
|
|
||||||
* \only_for_vectors
|
|
||||||
* \sa end(), cbegin()
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
inline typename DenseBase<Derived>::iterator DenseBase<Derived>::begin()
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
|
|
||||||
return iterator(derived(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** const version of begin() */
|
|
||||||
template<typename Derived>
|
|
||||||
inline typename DenseBase<Derived>::const_iterator DenseBase<Derived>::begin() const
|
|
||||||
{
|
|
||||||
return cbegin();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** returns a read-only const_iterator to the first element of the 1D vector or array
|
|
||||||
* \only_for_vectors
|
|
||||||
* \sa cend(), begin()
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
inline typename DenseBase<Derived>::const_iterator DenseBase<Derived>::cbegin() const
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
|
|
||||||
return const_iterator(derived(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** returns an iterator to the element following the last element of the 1D vector or array
|
|
||||||
* \only_for_vectors
|
|
||||||
* \sa begin(), cend()
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
inline typename DenseBase<Derived>::iterator DenseBase<Derived>::end()
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
|
|
||||||
return iterator(derived(), size());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** const version of end() */
|
|
||||||
template<typename Derived>
|
|
||||||
inline typename DenseBase<Derived>::const_iterator DenseBase<Derived>::end() const
|
|
||||||
{
|
|
||||||
return cend();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** returns a read-only const_iterator to the element following the last element of the 1D vector or array
|
|
||||||
* \only_for_vectors
|
|
||||||
* \sa begin(), cend()
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
inline typename DenseBase<Derived>::const_iterator DenseBase<Derived>::cend() const
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
|
|
||||||
return const_iterator(derived(), size());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_STLITERATORS_H
|
|
||||||
@@ -38,14 +38,6 @@ namespace Eigen {
|
|||||||
* \include Map_general_stride.cpp
|
* \include Map_general_stride.cpp
|
||||||
* Output: \verbinclude Map_general_stride.out
|
* Output: \verbinclude Map_general_stride.out
|
||||||
*
|
*
|
||||||
* Both strides can be negative. However, a negative stride of -1 cannot be specified at compile time
|
|
||||||
* because of the ambiguity with Dynamic which is defined to -1 (historically, negative strides were
|
|
||||||
* not allowed).
|
|
||||||
*
|
|
||||||
* Note that for compile-time vectors (ColsAtCompileTime==1 or RowsAtCompile==1),
|
|
||||||
* the inner stride is the pointer increment between two consecutive elements,
|
|
||||||
* regardless of storage layout.
|
|
||||||
*
|
|
||||||
* \sa class InnerStride, class OuterStride, \ref TopicStorageOrders
|
* \sa class InnerStride, class OuterStride, \ref TopicStorageOrders
|
||||||
*/
|
*/
|
||||||
template<int _OuterStrideAtCompileTime, int _InnerStrideAtCompileTime>
|
template<int _OuterStrideAtCompileTime, int _InnerStrideAtCompileTime>
|
||||||
@@ -63,8 +55,6 @@ class Stride
|
|||||||
Stride()
|
Stride()
|
||||||
: m_outer(OuterStrideAtCompileTime), m_inner(InnerStrideAtCompileTime)
|
: m_outer(OuterStrideAtCompileTime), m_inner(InnerStrideAtCompileTime)
|
||||||
{
|
{
|
||||||
// FIXME: for Eigen 4 we should use DynamicIndex instead of Dynamic.
|
|
||||||
// FIXME: for Eigen 4 we should also unify this API with fix<>
|
|
||||||
eigen_assert(InnerStrideAtCompileTime != Dynamic && OuterStrideAtCompileTime != Dynamic);
|
eigen_assert(InnerStrideAtCompileTime != Dynamic && OuterStrideAtCompileTime != Dynamic);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,6 +63,7 @@ class Stride
|
|||||||
Stride(Index outerStride, Index innerStride)
|
Stride(Index outerStride, Index innerStride)
|
||||||
: m_outer(outerStride), m_inner(innerStride)
|
: m_outer(outerStride), m_inner(innerStride)
|
||||||
{
|
{
|
||||||
|
eigen_assert(innerStride>=0 && outerStride>=0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Copy constructor */
|
/** Copy constructor */
|
||||||
@@ -82,10 +73,10 @@ class Stride
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
/** \returns the outer stride */
|
/** \returns the outer stride */
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index outer() const { return m_outer.value(); }
|
inline Index outer() const { return m_outer.value(); }
|
||||||
/** \returns the inner stride */
|
/** \returns the inner stride */
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index inner() const { return m_inner.value(); }
|
inline Index inner() const { return m_inner.value(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -30,13 +30,12 @@ public:
|
|||||||
typedef typename Base::DstXprType DstXprType;
|
typedef typename Base::DstXprType DstXprType;
|
||||||
typedef swap_assign_op<Scalar> Functor;
|
typedef swap_assign_op<Scalar> Functor;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC generic_dense_assignment_kernel(DstEvaluatorTypeT &dst, const SrcEvaluatorTypeT &src, const Functor &func, DstXprType& dstExpr)
|
||||||
generic_dense_assignment_kernel(DstEvaluatorTypeT &dst, const SrcEvaluatorTypeT &src, const Functor &func, DstXprType& dstExpr)
|
|
||||||
: Base(dst, src, func, dstExpr)
|
: Base(dst, src, func, dstExpr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<int StoreMode, int LoadMode, typename PacketType>
|
template<int StoreMode, int LoadMode, typename PacketType>
|
||||||
EIGEN_STRONG_INLINE void assignPacket(Index row, Index col)
|
void assignPacket(Index row, Index col)
|
||||||
{
|
{
|
||||||
PacketType tmp = m_src.template packet<LoadMode,PacketType>(row,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));
|
const_cast<SrcEvaluatorTypeT&>(m_src).template writePacket<LoadMode>(row,col, m_dst.template packet<StoreMode,PacketType>(row,col));
|
||||||
@@ -44,7 +43,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<int StoreMode, int LoadMode, typename PacketType>
|
template<int StoreMode, int LoadMode, typename PacketType>
|
||||||
EIGEN_STRONG_INLINE void assignPacket(Index index)
|
void assignPacket(Index index)
|
||||||
{
|
{
|
||||||
PacketType tmp = m_src.template packet<LoadMode,PacketType>(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));
|
const_cast<SrcEvaluatorTypeT&>(m_src).template writePacket<LoadMode>(index, m_dst.template packet<StoreMode,PacketType>(index));
|
||||||
@@ -53,7 +52,7 @@ public:
|
|||||||
|
|
||||||
// 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)
|
// 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>
|
template<int StoreMode, int LoadMode, typename PacketType>
|
||||||
EIGEN_STRONG_INLINE void assignPacketByOuterInner(Index outer, Index inner)
|
void assignPacketByOuterInner(Index outer, Index inner)
|
||||||
{
|
{
|
||||||
Index row = Base::rowIndexByOuterInner(outer, inner);
|
Index row = Base::rowIndexByOuterInner(outer, inner);
|
||||||
Index col = Base::colIndexByOuterInner(outer, inner);
|
Index col = Base::colIndexByOuterInner(outer, inner);
|
||||||
|
|||||||
@@ -61,27 +61,24 @@ template<typename MatrixType> class Transpose
|
|||||||
typedef typename internal::remove_all<MatrixType>::type NestedExpression;
|
typedef typename internal::remove_all<MatrixType>::type NestedExpression;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
explicit EIGEN_STRONG_INLINE Transpose(MatrixType& matrix) : m_matrix(matrix) {}
|
explicit inline Transpose(MatrixType& matrix) : m_matrix(matrix) {}
|
||||||
|
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Transpose)
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Transpose)
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC inline Index rows() const { return m_matrix.cols(); }
|
||||||
Index rows() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
|
EIGEN_DEVICE_FUNC inline Index cols() const { return m_matrix.rows(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
|
||||||
Index cols() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
|
|
||||||
|
|
||||||
/** \returns the nested expression */
|
/** \returns the nested expression */
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
const typename internal::remove_all<MatrixTypeNested>::type&
|
const typename internal::remove_all<MatrixTypeNested>::type&
|
||||||
nestedExpression() const { return m_matrix; }
|
nestedExpression() const { return m_matrix; }
|
||||||
|
|
||||||
/** \returns the nested expression */
|
/** \returns the nested expression */
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
typename internal::remove_reference<MatrixTypeNested>::type&
|
typename internal::remove_reference<MatrixTypeNested>::type&
|
||||||
nestedExpression() { return m_matrix; }
|
nestedExpression() { return m_matrix; }
|
||||||
|
|
||||||
/** \internal */
|
/** \internal */
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
void resize(Index nrows, Index ncols) {
|
void resize(Index nrows, Index ncols) {
|
||||||
m_matrix.resize(ncols,nrows);
|
m_matrix.resize(ncols,nrows);
|
||||||
}
|
}
|
||||||
@@ -125,10 +122,8 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
|
|||||||
EIGEN_DENSE_PUBLIC_INTERFACE(Transpose<MatrixType>)
|
EIGEN_DENSE_PUBLIC_INTERFACE(Transpose<MatrixType>)
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TransposeImpl)
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TransposeImpl)
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC inline Index innerStride() const { return derived().nestedExpression().innerStride(); }
|
||||||
Index innerStride() const { return derived().nestedExpression().innerStride(); }
|
EIGEN_DEVICE_FUNC inline Index outerStride() const { return derived().nestedExpression().outerStride(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
Index outerStride() const { return derived().nestedExpression().outerStride(); }
|
|
||||||
|
|
||||||
typedef typename internal::conditional<
|
typedef typename internal::conditional<
|
||||||
internal::is_lvalue<MatrixType>::value,
|
internal::is_lvalue<MatrixType>::value,
|
||||||
@@ -136,20 +131,18 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
|
|||||||
const Scalar
|
const Scalar
|
||||||
>::type ScalarWithConstIfNotLvalue;
|
>::type ScalarWithConstIfNotLvalue;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC inline ScalarWithConstIfNotLvalue* data() { return derived().nestedExpression().data(); }
|
||||||
ScalarWithConstIfNotLvalue* data() { return derived().nestedExpression().data(); }
|
EIGEN_DEVICE_FUNC inline const Scalar* data() const { return derived().nestedExpression().data(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
const Scalar* data() const { return derived().nestedExpression().data(); }
|
|
||||||
|
|
||||||
// FIXME: shall we keep the const version of coeffRef?
|
// FIXME: shall we keep the const version of coeffRef?
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
const Scalar& coeffRef(Index rowId, Index colId) const
|
inline const Scalar& coeffRef(Index rowId, Index colId) const
|
||||||
{
|
{
|
||||||
return derived().nestedExpression().coeffRef(colId, rowId);
|
return derived().nestedExpression().coeffRef(colId, rowId);
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
const Scalar& coeffRef(Index index) const
|
inline const Scalar& coeffRef(Index index) const
|
||||||
{
|
{
|
||||||
return derived().nestedExpression().coeffRef(index);
|
return derived().nestedExpression().coeffRef(index);
|
||||||
}
|
}
|
||||||
@@ -177,8 +170,7 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
|
|||||||
*
|
*
|
||||||
* \sa transposeInPlace(), adjoint() */
|
* \sa transposeInPlace(), adjoint() */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC inline Transpose<Derived>
|
||||||
typename DenseBase<Derived>::TransposeReturnType
|
|
||||||
DenseBase<Derived>::transpose()
|
DenseBase<Derived>::transpose()
|
||||||
{
|
{
|
||||||
return TransposeReturnType(derived());
|
return TransposeReturnType(derived());
|
||||||
@@ -190,8 +182,7 @@ DenseBase<Derived>::transpose()
|
|||||||
*
|
*
|
||||||
* \sa transposeInPlace(), adjoint() */
|
* \sa transposeInPlace(), adjoint() */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC inline typename DenseBase<Derived>::ConstTransposeReturnType
|
||||||
const typename DenseBase<Derived>::ConstTransposeReturnType
|
|
||||||
DenseBase<Derived>::transpose() const
|
DenseBase<Derived>::transpose() const
|
||||||
{
|
{
|
||||||
return ConstTransposeReturnType(derived());
|
return ConstTransposeReturnType(derived());
|
||||||
@@ -239,10 +230,11 @@ struct inplace_transpose_selector;
|
|||||||
template<typename MatrixType>
|
template<typename MatrixType>
|
||||||
struct inplace_transpose_selector<MatrixType,true,false> { // square matrix
|
struct inplace_transpose_selector<MatrixType,true,false> { // square matrix
|
||||||
static void run(MatrixType& m) {
|
static void run(MatrixType& m) {
|
||||||
m.matrix().template triangularView<StrictlyUpper>().swap(m.matrix().transpose().template triangularView<StrictlyUpper>());
|
m.matrix().template triangularView<StrictlyUpper>().swap(m.matrix().transpose());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: vectorized path is currently limited to LargestPacketSize x LargestPacketSize cases only.
|
||||||
template<typename MatrixType>
|
template<typename MatrixType>
|
||||||
struct inplace_transpose_selector<MatrixType,true,true> { // PacketSize x PacketSize
|
struct inplace_transpose_selector<MatrixType,true,true> { // PacketSize x PacketSize
|
||||||
static void run(MatrixType& m) {
|
static void run(MatrixType& m) {
|
||||||
@@ -259,66 +251,16 @@ struct inplace_transpose_selector<MatrixType,true,true> { // PacketSize x Packet
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename MatrixType, Index Alignment>
|
|
||||||
void BlockedInPlaceTranspose(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;
|
|
||||||
eigen_assert(m.rows() == m.cols());
|
|
||||||
int row_start = 0;
|
|
||||||
for (; row_start + PacketSize <= m.rows(); row_start += PacketSize) {
|
|
||||||
for (int col_start = row_start; col_start + PacketSize <= m.cols(); col_start += PacketSize) {
|
|
||||||
PacketBlock<Packet> A;
|
|
||||||
if (row_start == col_start) {
|
|
||||||
for (Index i=0; i<PacketSize; ++i)
|
|
||||||
A.packet[i] = m.template packetByOuterInner<Alignment>(row_start + i,col_start);
|
|
||||||
internal::ptranspose(A);
|
|
||||||
for (Index i=0; i<PacketSize; ++i)
|
|
||||||
m.template writePacket<Alignment>(m.rowIndexByOuterInner(row_start + i, col_start), m.colIndexByOuterInner(row_start + i,col_start), A.packet[i]);
|
|
||||||
} else {
|
|
||||||
PacketBlock<Packet> B;
|
|
||||||
for (Index i=0; i<PacketSize; ++i) {
|
|
||||||
A.packet[i] = m.template packetByOuterInner<Alignment>(row_start + i,col_start);
|
|
||||||
B.packet[i] = m.template packetByOuterInner<Alignment>(col_start + i, row_start);
|
|
||||||
}
|
|
||||||
internal::ptranspose(A);
|
|
||||||
internal::ptranspose(B);
|
|
||||||
for (Index i=0; i<PacketSize; ++i) {
|
|
||||||
m.template writePacket<Alignment>(m.rowIndexByOuterInner(row_start + i, col_start), m.colIndexByOuterInner(row_start + i,col_start), B.packet[i]);
|
|
||||||
m.template writePacket<Alignment>(m.rowIndexByOuterInner(col_start + i, row_start), m.colIndexByOuterInner(col_start + i,row_start), A.packet[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (Index row = row_start; row < m.rows(); ++row) {
|
|
||||||
m.matrix().row(row).head(row).swap(
|
|
||||||
m.matrix().col(row).head(row).transpose());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename MatrixType,bool MatchPacketSize>
|
template<typename MatrixType,bool MatchPacketSize>
|
||||||
struct inplace_transpose_selector<MatrixType,false,MatchPacketSize> { // non square or dynamic matrix
|
struct inplace_transpose_selector<MatrixType,false,MatchPacketSize> { // non square matrix
|
||||||
static void run(MatrixType& m) {
|
static void run(MatrixType& m) {
|
||||||
typedef typename MatrixType::Scalar Scalar;
|
if (m.rows()==m.cols())
|
||||||
if (m.rows() == m.cols()) {
|
m.matrix().template triangularView<StrictlyUpper>().swap(m.matrix().transpose());
|
||||||
const Index PacketSize = internal::packet_traits<Scalar>::size;
|
else
|
||||||
if (!NumTraits<Scalar>::IsComplex && m.rows() >= PacketSize) {
|
|
||||||
if ((m.rows() % PacketSize) == 0)
|
|
||||||
BlockedInPlaceTranspose<MatrixType,internal::evaluator<MatrixType>::Alignment>(m);
|
|
||||||
else
|
|
||||||
BlockedInPlaceTranspose<MatrixType,Unaligned>(m);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m.matrix().template triangularView<StrictlyUpper>().swap(m.matrix().transpose().template triangularView<StrictlyUpper>());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m = m.transpose().eval();
|
m = m.transpose().eval();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
/** This is the "in place" version of transpose(): it replaces \c *this by its own transpose.
|
/** This is the "in place" version of transpose(): it replaces \c *this by its own transpose.
|
||||||
@@ -451,8 +393,7 @@ struct checkTransposeAliasing_impl<Derived, OtherDerived, false>
|
|||||||
template<typename Dst, typename Src>
|
template<typename Dst, typename Src>
|
||||||
void check_for_aliasing(const Dst &dst, const Src &src)
|
void check_for_aliasing(const Dst &dst, const Src &src)
|
||||||
{
|
{
|
||||||
if((!Dst::IsVectorAtCompileTime) && dst.rows()>1 && dst.cols()>1)
|
internal::checkTransposeAliasing_impl<Dst, Src>::run(dst, src);
|
||||||
internal::checkTransposeAliasing_impl<Dst, Src>::run(dst, src);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|||||||
@@ -23,9 +23,7 @@ class TranspositionsBase
|
|||||||
typedef typename IndicesType::Scalar StorageIndex;
|
typedef typename IndicesType::Scalar StorageIndex;
|
||||||
typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
|
typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
Derived& derived() { return *static_cast<Derived*>(this); }
|
Derived& derived() { return *static_cast<Derived*>(this); }
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
const Derived& derived() const { return *static_cast<const Derived*>(this); }
|
const Derived& derived() const { return *static_cast<const Derived*>(this); }
|
||||||
|
|
||||||
/** Copies the \a other transpositions into \c *this */
|
/** Copies the \a other transpositions into \c *this */
|
||||||
@@ -37,17 +35,13 @@ class TranspositionsBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the number of transpositions */
|
/** \returns the number of transpositions */
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
Index size() const { return indices().size(); }
|
Index size() const { return indices().size(); }
|
||||||
/** \returns the number of rows of the equivalent permutation matrix */
|
/** \returns the number of rows of the equivalent permutation matrix */
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
Index rows() const { return indices().size(); }
|
Index rows() const { return indices().size(); }
|
||||||
/** \returns the number of columns of the equivalent permutation matrix */
|
/** \returns the number of columns of the equivalent permutation matrix */
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
Index cols() const { return indices().size(); }
|
Index cols() const { return indices().size(); }
|
||||||
|
|
||||||
/** Direct access to the underlying index vector */
|
/** Direct access to the underlying index vector */
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline const StorageIndex& 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 */
|
/** Direct access to the underlying index vector */
|
||||||
inline StorageIndex& coeffRef(Index i) { return indices().coeffRef(i); }
|
inline StorageIndex& coeffRef(Index i) { return indices().coeffRef(i); }
|
||||||
@@ -61,10 +55,8 @@ class TranspositionsBase
|
|||||||
inline StorageIndex& operator[](Index i) { return indices()(i); }
|
inline StorageIndex& operator[](Index i) { return indices()(i); }
|
||||||
|
|
||||||
/** const version of indices(). */
|
/** const version of indices(). */
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
const IndicesType& indices() const { return derived().indices(); }
|
const IndicesType& indices() const { return derived().indices(); }
|
||||||
/** \returns a reference to the stored array representing the transpositions. */
|
/** \returns a reference to the stored array representing the transpositions. */
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
IndicesType& indices() { return derived().indices(); }
|
IndicesType& indices() { return derived().indices(); }
|
||||||
|
|
||||||
/** Resizes to given size. */
|
/** Resizes to given size. */
|
||||||
@@ -81,7 +73,7 @@ class TranspositionsBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: do we want such methods ?
|
// FIXME: do we want such methods ?
|
||||||
// might be useful when the target matrix expression is complex, e.g.:
|
// might be usefull when the target matrix expression is complex, e.g.:
|
||||||
// object.matrix().block(..,..,..,..) = trans * object.matrix().block(..,..,..,..);
|
// object.matrix().block(..,..,..,..) = trans * object.matrix().block(..,..,..,..);
|
||||||
/*
|
/*
|
||||||
template<typename MatrixType>
|
template<typename MatrixType>
|
||||||
@@ -186,10 +178,8 @@ class Transpositions : public TranspositionsBase<Transpositions<SizeAtCompileTim
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
/** const version of indices(). */
|
/** const version of indices(). */
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
const IndicesType& indices() const { return m_indices; }
|
const IndicesType& indices() const { return m_indices; }
|
||||||
/** \returns a reference to the stored array representing the transpositions. */
|
/** \returns a reference to the stored array representing the transpositions. */
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
IndicesType& indices() { return m_indices; }
|
IndicesType& indices() { return m_indices; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -247,11 +237,9 @@ class Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,_StorageIndex>,P
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** const version of indices(). */
|
/** const version of indices(). */
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
const IndicesType& indices() const { return m_indices; }
|
const IndicesType& indices() const { return m_indices; }
|
||||||
|
|
||||||
/** \returns a reference to the stored array representing the transpositions. */
|
/** \returns a reference to the stored array representing the transpositions. */
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
IndicesType& indices() { return m_indices; }
|
IndicesType& indices() { return m_indices; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -291,11 +279,9 @@ class TranspositionsWrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** const version of indices(). */
|
/** const version of indices(). */
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
const IndicesType& indices() const { return m_indices; }
|
const IndicesType& indices() const { return m_indices; }
|
||||||
|
|
||||||
/** \returns a reference to the stored array representing the transpositions. */
|
/** \returns a reference to the stored array representing the transpositions. */
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
IndicesType& indices() { return m_indices; }
|
IndicesType& indices() { return m_indices; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -349,12 +335,9 @@ class Transpose<TranspositionsBase<TranspositionsDerived> >
|
|||||||
|
|
||||||
explicit Transpose(const TranspositionType& t) : m_transpositions(t) {}
|
explicit Transpose(const TranspositionType& t) : m_transpositions(t) {}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
Index size() const { return m_transpositions.size(); }
|
||||||
Index size() const EIGEN_NOEXCEPT { return m_transpositions.size(); }
|
Index rows() const { return m_transpositions.size(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
Index cols() const { return m_transpositions.size(); }
|
||||||
Index rows() const EIGEN_NOEXCEPT { return m_transpositions.size(); }
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
|
||||||
Index cols() const EIGEN_NOEXCEPT { return m_transpositions.size(); }
|
|
||||||
|
|
||||||
/** \returns the \a matrix with the inverse transpositions applied to the columns.
|
/** \returns the \a matrix with the inverse transpositions applied to the columns.
|
||||||
*/
|
*/
|
||||||
@@ -374,7 +357,6 @@ class Transpose<TranspositionsBase<TranspositionsDerived> >
|
|||||||
return Product<Transpose, OtherDerived, AliasFreeProduct>(*this, matrix.derived());
|
return Product<Transpose, OtherDerived, AliasFreeProduct>(*this, matrix.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
const TranspositionType& nestedExpression() const { return m_transpositions; }
|
const TranspositionType& nestedExpression() const { return m_transpositions; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -53,19 +53,18 @@ template<typename Derived> class TriangularBase : public EigenBase<Derived>
|
|||||||
typedef Derived const& Nested;
|
typedef Derived const& Nested;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline TriangularBase() { eigen_assert(!((int(Mode) & int(UnitDiag)) && (int(Mode) & int(ZeroDiag)))); }
|
inline TriangularBase() { eigen_assert(!((Mode&UnitDiag) && (Mode&ZeroDiag))); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index rows() const EIGEN_NOEXCEPT { return derived().rows(); }
|
inline Index rows() const { return derived().rows(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index cols() const EIGEN_NOEXCEPT { return derived().cols(); }
|
inline Index cols() const { return derived().cols(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index outerStride() const EIGEN_NOEXCEPT { return derived().outerStride(); }
|
inline Index outerStride() const { return derived().outerStride(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index innerStride() const EIGEN_NOEXCEPT { return derived().innerStride(); }
|
inline Index innerStride() const { return derived().innerStride(); }
|
||||||
|
|
||||||
// dummy resize function
|
// dummy resize function
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
void resize(Index rows, Index cols)
|
void resize(Index rows, Index cols)
|
||||||
{
|
{
|
||||||
EIGEN_UNUSED_VARIABLE(rows);
|
EIGEN_UNUSED_VARIABLE(rows);
|
||||||
@@ -100,10 +99,12 @@ template<typename Derived> class TriangularBase : public EigenBase<Derived>
|
|||||||
return coeffRef(row,col);
|
return coeffRef(row,col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
|
inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline Derived& derived() { return *static_cast<Derived*>(this); }
|
inline Derived& derived() { return *static_cast<Derived*>(this); }
|
||||||
|
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
|
||||||
template<typename DenseDerived>
|
template<typename DenseDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
@@ -196,7 +197,6 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
|
|||||||
typedef typename internal::traits<TriangularView>::MatrixTypeNestedNonRef MatrixTypeNestedNonRef;
|
typedef typename internal::traits<TriangularView>::MatrixTypeNestedNonRef MatrixTypeNestedNonRef;
|
||||||
|
|
||||||
typedef typename internal::remove_all<typename MatrixType::ConjugateReturnType>::type MatrixConjugateReturnType;
|
typedef typename internal::remove_all<typename MatrixType::ConjugateReturnType>::type MatrixConjugateReturnType;
|
||||||
typedef TriangularView<typename internal::add_const<MatrixType>::type, _Mode> ConstTriangularView;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -220,11 +220,11 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
|
|||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TriangularView)
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TriangularView)
|
||||||
|
|
||||||
/** \copydoc EigenBase::rows() */
|
/** \copydoc EigenBase::rows() */
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index rows() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
|
inline Index rows() const { return m_matrix.rows(); }
|
||||||
/** \copydoc EigenBase::cols() */
|
/** \copydoc EigenBase::cols() */
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
|
inline Index cols() const { return m_matrix.cols(); }
|
||||||
|
|
||||||
/** \returns a const reference to the nested expression */
|
/** \returns a const reference to the nested expression */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
@@ -240,18 +240,6 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
|
|||||||
inline const ConjugateReturnType conjugate() const
|
inline const ConjugateReturnType conjugate() const
|
||||||
{ return ConjugateReturnType(m_matrix.conjugate()); }
|
{ return ConjugateReturnType(m_matrix.conjugate()); }
|
||||||
|
|
||||||
/** \returns an expression of the complex conjugate of \c *this if Cond==true,
|
|
||||||
* returns \c *this otherwise.
|
|
||||||
*/
|
|
||||||
template<bool Cond>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline typename internal::conditional<Cond,ConjugateReturnType,ConstTriangularView>::type
|
|
||||||
conjugateIf() const
|
|
||||||
{
|
|
||||||
typedef typename internal::conditional<Cond,ConjugateReturnType,ConstTriangularView>::type ReturnType;
|
|
||||||
return ReturnType(m_matrix.template conjugateIf<Cond>());
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef TriangularView<const typename MatrixType::AdjointReturnType,TransposeMode> AdjointReturnType;
|
typedef TriangularView<const typename MatrixType::AdjointReturnType,TransposeMode> AdjointReturnType;
|
||||||
/** \sa MatrixBase::adjoint() const */
|
/** \sa MatrixBase::adjoint() const */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
@@ -440,19 +428,21 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
TriangularViewType& operator=(const MatrixBase<OtherDerived>& other);
|
TriangularViewType& operator=(const MatrixBase<OtherDerived>& other);
|
||||||
|
|
||||||
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
TriangularViewType& operator=(const TriangularViewImpl& other)
|
TriangularViewType& operator=(const TriangularViewImpl& other)
|
||||||
{ return *this = other.derived().nestedExpression(); }
|
{ return *this = other.derived().nestedExpression(); }
|
||||||
|
|
||||||
template<typename OtherDerived>
|
|
||||||
/** \deprecated */
|
/** \deprecated */
|
||||||
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC
|
template<typename OtherDerived>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
void lazyAssign(const TriangularBase<OtherDerived>& other);
|
void lazyAssign(const TriangularBase<OtherDerived>& other);
|
||||||
|
|
||||||
template<typename OtherDerived>
|
|
||||||
/** \deprecated */
|
/** \deprecated */
|
||||||
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC
|
template<typename OtherDerived>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
void lazyAssign(const MatrixBase<OtherDerived>& other);
|
void lazyAssign(const MatrixBase<OtherDerived>& other);
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Efficient triangular matrix times vector/matrix product */
|
/** Efficient triangular matrix times vector/matrix product */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
@@ -478,7 +468,7 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
|||||||
* \a Side==OnTheLeft (the default), or the right-inverse-multiply \a other * inverse(\c *this) if
|
* \a Side==OnTheLeft (the default), or the right-inverse-multiply \a other * inverse(\c *this) if
|
||||||
* \a Side==OnTheRight.
|
* \a Side==OnTheRight.
|
||||||
*
|
*
|
||||||
* Note that the template parameter \c Side can be omitted, in which case \c Side==OnTheLeft
|
* Note that the template parameter \c Side can be ommitted, in which case \c Side==OnTheLeft
|
||||||
*
|
*
|
||||||
* The matrix \c *this must be triangular and invertible (i.e., all the coefficients of the
|
* The matrix \c *this must be triangular and invertible (i.e., all the coefficients of the
|
||||||
* diagonal must be non zero). It works as a forward (resp. backward) substitution if \c *this
|
* diagonal must be non zero). It works as a forward (resp. backward) substitution if \c *this
|
||||||
@@ -496,6 +486,7 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
|||||||
* \sa TriangularView::solveInPlace()
|
* \sa TriangularView::solveInPlace()
|
||||||
*/
|
*/
|
||||||
template<int Side, typename Other>
|
template<int Side, typename Other>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
inline const internal::triangular_solve_retval<Side,TriangularViewType, Other>
|
inline const internal::triangular_solve_retval<Side,TriangularViewType, Other>
|
||||||
solve(const MatrixBase<Other>& other) const;
|
solve(const MatrixBase<Other>& other) const;
|
||||||
|
|
||||||
@@ -504,7 +495,7 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
|||||||
* \warning The parameter is only marked 'const' to make the C++ compiler accept a temporary expression here.
|
* \warning The parameter is only marked 'const' to make the C++ compiler accept a temporary expression here.
|
||||||
* This function will const_cast it, so constness isn't honored here.
|
* This function will const_cast it, so constness isn't honored here.
|
||||||
*
|
*
|
||||||
* Note that the template parameter \c Side can be omitted, in which case \c Side==OnTheLeft
|
* Note that the template parameter \c Side can be ommitted, in which case \c Side==OnTheLeft
|
||||||
*
|
*
|
||||||
* See TriangularView:solve() for the details.
|
* See TriangularView:solve() for the details.
|
||||||
*/
|
*/
|
||||||
@@ -520,16 +511,20 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
|||||||
/** Swaps the coefficients of the common triangular parts of two matrices */
|
/** Swaps the coefficients of the common triangular parts of two matrices */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
|
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
void swap(TriangularBase<OtherDerived> &other)
|
||||||
|
#else
|
||||||
void swap(TriangularBase<OtherDerived> const & other)
|
void swap(TriangularBase<OtherDerived> const & other)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_LVALUE(OtherDerived);
|
EIGEN_STATIC_ASSERT_LVALUE(OtherDerived);
|
||||||
call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
|
call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Shortcut for \code (*this).swap(other.triangularView<(*this)::Mode>()) \endcode */
|
/** \deprecated
|
||||||
|
* Shortcut for \code (*this).swap(other.triangularView<(*this)::Mode>()) \endcode */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
/** \deprecated */
|
EIGEN_DEVICE_FUNC
|
||||||
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC
|
|
||||||
void swap(MatrixBase<OtherDerived> const & other)
|
void swap(MatrixBase<OtherDerived> const & other)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_LVALUE(OtherDerived);
|
EIGEN_STATIC_ASSERT_LVALUE(OtherDerived);
|
||||||
@@ -544,10 +539,9 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
|||||||
this->solveInPlace(dst);
|
this->solveInPlace(dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ProductType>
|
template<typename ProductType>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TriangularViewType& _assignProduct(const ProductType& prod, const Scalar& alpha,
|
EIGEN_DEVICE_FUNC
|
||||||
bool beta);
|
EIGEN_STRONG_INLINE TriangularViewType& _assignProduct(const ProductType& prod, const Scalar& alpha, bool beta);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
EIGEN_DEFAULT_COPY_CONSTRUCTOR(TriangularViewImpl)
|
EIGEN_DEFAULT_COPY_CONSTRUCTOR(TriangularViewImpl)
|
||||||
EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(TriangularViewImpl)
|
EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(TriangularViewImpl)
|
||||||
@@ -632,8 +626,7 @@ EIGEN_DEVICE_FUNC void TriangularBase<Derived>::evalTo(MatrixBase<DenseDerived>
|
|||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<unsigned int Mode>
|
template<unsigned int Mode>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC typename MatrixBase<Derived>::template TriangularViewReturnType<Mode>::Type
|
||||||
typename MatrixBase<Derived>::template TriangularViewReturnType<Mode>::Type
|
|
||||||
MatrixBase<Derived>::triangularView()
|
MatrixBase<Derived>::triangularView()
|
||||||
{
|
{
|
||||||
return typename TriangularViewReturnType<Mode>::Type(derived());
|
return typename TriangularViewReturnType<Mode>::Type(derived());
|
||||||
@@ -642,8 +635,7 @@ MatrixBase<Derived>::triangularView()
|
|||||||
/** This is the const version of MatrixBase::triangularView() */
|
/** This is the const version of MatrixBase::triangularView() */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<unsigned int Mode>
|
template<unsigned int Mode>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC typename MatrixBase<Derived>::template ConstTriangularViewReturnType<Mode>::Type
|
||||||
typename MatrixBase<Derived>::template ConstTriangularViewReturnType<Mode>::Type
|
|
||||||
MatrixBase<Derived>::triangularView() const
|
MatrixBase<Derived>::triangularView() const
|
||||||
{
|
{
|
||||||
return typename ConstTriangularViewReturnType<Mode>::Type(derived());
|
return typename ConstTriangularViewReturnType<Mode>::Type(derived());
|
||||||
@@ -725,7 +717,6 @@ struct unary_evaluator<TriangularView<MatrixType,Mode>, IndexBased>
|
|||||||
{
|
{
|
||||||
typedef TriangularView<MatrixType,Mode> XprType;
|
typedef TriangularView<MatrixType,Mode> XprType;
|
||||||
typedef evaluator<typename internal::remove_all<MatrixType>::type> Base;
|
typedef evaluator<typename internal::remove_all<MatrixType>::type> Base;
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
unary_evaluator(const XprType &xpr) : Base(xpr.nestedExpression()) {}
|
unary_evaluator(const XprType &xpr) : Base(xpr.nestedExpression()) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -812,7 +803,7 @@ void call_triangular_assignment_loop(DstXprType& dst, const SrcXprType& src, con
|
|||||||
enum {
|
enum {
|
||||||
unroll = DstXprType::SizeAtCompileTime != Dynamic
|
unroll = DstXprType::SizeAtCompileTime != Dynamic
|
||||||
&& SrcEvaluatorType::CoeffReadCost < HugeCost
|
&& SrcEvaluatorType::CoeffReadCost < HugeCost
|
||||||
&& DstXprType::SizeAtCompileTime * (int(DstEvaluatorType::CoeffReadCost) + int(SrcEvaluatorType::CoeffReadCost)) / 2 <= EIGEN_UNROLLING_LIMIT
|
&& DstXprType::SizeAtCompileTime * (DstEvaluatorType::CoeffReadCost+SrcEvaluatorType::CoeffReadCost) / 2 <= EIGEN_UNROLLING_LIMIT
|
||||||
};
|
};
|
||||||
|
|
||||||
triangular_assignment_loop<Kernel, Mode, unroll ? int(DstXprType::SizeAtCompileTime) : Dynamic, SetOpposite>::run(kernel);
|
triangular_assignment_loop<Kernel, Mode, unroll ? int(DstXprType::SizeAtCompileTime) : Dynamic, SetOpposite>::run(kernel);
|
||||||
@@ -846,7 +837,7 @@ struct Assignment<DstXprType, SrcXprType, Functor, Triangular2Dense>
|
|||||||
{
|
{
|
||||||
EIGEN_DEVICE_FUNC static void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
|
EIGEN_DEVICE_FUNC static void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
|
||||||
{
|
{
|
||||||
call_triangular_assignment_loop<SrcXprType::Mode, (int(SrcXprType::Mode) & int(SelfAdjoint)) == 0>(dst, src, func);
|
call_triangular_assignment_loop<SrcXprType::Mode, (SrcXprType::Mode&SelfAdjoint)==0>(dst, src, func);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -944,7 +935,7 @@ template<typename DenseDerived>
|
|||||||
EIGEN_DEVICE_FUNC void TriangularBase<Derived>::evalToLazy(MatrixBase<DenseDerived> &other) const
|
EIGEN_DEVICE_FUNC void TriangularBase<Derived>::evalToLazy(MatrixBase<DenseDerived> &other) const
|
||||||
{
|
{
|
||||||
other.derived().resize(this->rows(), this->cols());
|
other.derived().resize(this->rows(), this->cols());
|
||||||
internal::call_triangular_assignment_loop<Derived::Mode, (int(Derived::Mode) & int(SelfAdjoint)) == 0 /* SetOpposite */>(other.derived(), derived().nestedExpression());
|
internal::call_triangular_assignment_loop<Derived::Mode,(Derived::Mode&SelfAdjoint)==0 /* SetOpposite */>(other.derived(), derived().nestedExpression());
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
@@ -954,14 +945,14 @@ template< typename DstXprType, typename Lhs, typename Rhs, typename Scalar>
|
|||||||
struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
|
struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
|
||||||
{
|
{
|
||||||
typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
|
typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
|
||||||
static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,typename SrcXprType::Scalar> &)
|
static EIGEN_DEVICE_FUNC void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,typename SrcXprType::Scalar> &)
|
||||||
{
|
{
|
||||||
Index dstRows = src.rows();
|
Index dstRows = src.rows();
|
||||||
Index dstCols = src.cols();
|
Index dstCols = src.cols();
|
||||||
if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
|
if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
|
||||||
dst.resize(dstRows, dstCols);
|
dst.resize(dstRows, dstCols);
|
||||||
|
|
||||||
dst._assignProduct(src, Scalar(1), false);
|
dst._assignProduct(src, 1, 0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -970,9 +961,9 @@ template< typename DstXprType, typename Lhs, typename Rhs, typename Scalar>
|
|||||||
struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::add_assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
|
struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::add_assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
|
||||||
{
|
{
|
||||||
typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
|
typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
|
||||||
static void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<Scalar,typename SrcXprType::Scalar> &)
|
static EIGEN_DEVICE_FUNC void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<Scalar,typename SrcXprType::Scalar> &)
|
||||||
{
|
{
|
||||||
dst._assignProduct(src, Scalar(1), true);
|
dst._assignProduct(src, 1, 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -981,9 +972,9 @@ template< typename DstXprType, typename Lhs, typename Rhs, typename Scalar>
|
|||||||
struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::sub_assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
|
struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::sub_assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
|
||||||
{
|
{
|
||||||
typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
|
typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
|
||||||
static void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<Scalar,typename SrcXprType::Scalar> &)
|
static EIGEN_DEVICE_FUNC void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<Scalar,typename SrcXprType::Scalar> &)
|
||||||
{
|
{
|
||||||
dst._assignProduct(src, Scalar(-1), true);
|
dst._assignProduct(src, -1, 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ struct traits<VectorBlock<VectorType, Size> >
|
|||||||
* It is the return type of DenseBase::segment(Index,Index) and DenseBase::segment<int>(Index) and
|
* It is the return type of DenseBase::segment(Index,Index) and DenseBase::segment<int>(Index) and
|
||||||
* most of the time this is the only way it is used.
|
* most of the time this is the only way it is used.
|
||||||
*
|
*
|
||||||
* However, if you want to directly manipulate sub-vector expressions,
|
* However, if you want to directly maniputate sub-vector expressions,
|
||||||
* for instance if you want to write a function returning such an expression, you
|
* for instance if you want to write a function returning such an expression, you
|
||||||
* will need to use this class.
|
* will need to use this class.
|
||||||
*
|
*
|
||||||
@@ -71,8 +71,8 @@ template<typename VectorType, int Size> class VectorBlock
|
|||||||
|
|
||||||
/** Dynamic-size constructor
|
/** Dynamic-size constructor
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
VectorBlock(VectorType& vector, Index start, Index size)
|
inline VectorBlock(VectorType& vector, Index start, Index size)
|
||||||
: Base(vector,
|
: Base(vector,
|
||||||
IsColVector ? start : 0, IsColVector ? 0 : start,
|
IsColVector ? start : 0, IsColVector ? 0 : start,
|
||||||
IsColVector ? size : 1, IsColVector ? 1 : size)
|
IsColVector ? size : 1, IsColVector ? 1 : size)
|
||||||
@@ -82,8 +82,8 @@ template<typename VectorType, int Size> class VectorBlock
|
|||||||
|
|
||||||
/** Fixed-size constructor
|
/** Fixed-size constructor
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC
|
||||||
VectorBlock(VectorType& vector, Index start)
|
inline VectorBlock(VectorType& vector, Index start)
|
||||||
: Base(vector, IsColVector ? start : 0, IsColVector ? 0 : start)
|
: Base(vector, IsColVector ? start : 0, IsColVector ? 0 : start)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorBlock);
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorBlock);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
// for linear algebra.
|
// for linear algebra.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2008-2019 Gael Guennebaud <gael.guennebaud@inria.fr>
|
// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// This Source Code Form is subject to the terms of the Mozilla
|
||||||
@@ -65,10 +65,10 @@ class PartialReduxExpr : public internal::dense_xpr_base< PartialReduxExpr<Matri
|
|||||||
explicit PartialReduxExpr(const MatrixType& mat, const MemberOp& func = MemberOp())
|
explicit PartialReduxExpr(const MatrixType& mat, const MemberOp& func = MemberOp())
|
||||||
: m_matrix(mat), m_functor(func) {}
|
: m_matrix(mat), m_functor(func) {}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
Index rows() const EIGEN_NOEXCEPT { return (Direction==Vertical ? 1 : m_matrix.rows()); }
|
Index rows() const { return (Direction==Vertical ? 1 : m_matrix.rows()); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
EIGEN_DEVICE_FUNC
|
||||||
Index cols() const EIGEN_NOEXCEPT { return (Direction==Horizontal ? 1 : m_matrix.cols()); }
|
Index cols() const { return (Direction==Horizontal ? 1 : m_matrix.cols()); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
typename MatrixType::Nested nestedExpression() const { return m_matrix; }
|
typename MatrixType::Nested nestedExpression() const { return m_matrix; }
|
||||||
@@ -81,46 +81,39 @@ class PartialReduxExpr : public internal::dense_xpr_base< PartialReduxExpr<Matri
|
|||||||
const MemberOp m_functor;
|
const MemberOp m_functor;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename A,typename B> struct partial_redux_dummy_func;
|
#define EIGEN_MEMBER_FUNCTOR(MEMBER,COST) \
|
||||||
|
template <typename ResultType> \
|
||||||
#define EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(MEMBER,COST,VECTORIZABLE,BINARYOP) \
|
struct member_##MEMBER { \
|
||||||
template <typename ResultType,typename Scalar> \
|
EIGEN_EMPTY_STRUCT_CTOR(member_##MEMBER) \
|
||||||
struct member_##MEMBER { \
|
typedef ResultType result_type; \
|
||||||
EIGEN_EMPTY_STRUCT_CTOR(member_##MEMBER) \
|
template<typename Scalar, int Size> struct Cost \
|
||||||
typedef ResultType result_type; \
|
{ enum { value = COST }; }; \
|
||||||
typedef BINARYOP<Scalar,Scalar> BinaryOp; \
|
template<typename XprType> \
|
||||||
template<int Size> struct Cost { enum { value = COST }; }; \
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
|
||||||
enum { Vectorizable = VECTORIZABLE }; \
|
ResultType operator()(const XprType& mat) const \
|
||||||
template<typename XprType> \
|
{ return mat.MEMBER(); } \
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
|
|
||||||
ResultType operator()(const XprType& mat) const \
|
|
||||||
{ return mat.MEMBER(); } \
|
|
||||||
BinaryOp binaryFunc() const { return BinaryOp(); } \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define EIGEN_MEMBER_FUNCTOR(MEMBER,COST) \
|
|
||||||
EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(MEMBER,COST,0,partial_redux_dummy_func)
|
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
EIGEN_MEMBER_FUNCTOR(squaredNorm, Size * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
|
||||||
EIGEN_MEMBER_FUNCTOR(norm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
|
EIGEN_MEMBER_FUNCTOR(norm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
|
||||||
EIGEN_MEMBER_FUNCTOR(stableNorm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
|
EIGEN_MEMBER_FUNCTOR(stableNorm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
|
||||||
EIGEN_MEMBER_FUNCTOR(blueNorm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
|
EIGEN_MEMBER_FUNCTOR(blueNorm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
|
||||||
EIGEN_MEMBER_FUNCTOR(hypotNorm, (Size-1) * functor_traits<scalar_hypot_op<Scalar> >::Cost );
|
EIGEN_MEMBER_FUNCTOR(hypotNorm, (Size-1) * functor_traits<scalar_hypot_op<Scalar> >::Cost );
|
||||||
|
EIGEN_MEMBER_FUNCTOR(sum, (Size-1)*NumTraits<Scalar>::AddCost);
|
||||||
|
EIGEN_MEMBER_FUNCTOR(mean, (Size-1)*NumTraits<Scalar>::AddCost + NumTraits<Scalar>::MulCost);
|
||||||
|
EIGEN_MEMBER_FUNCTOR(minCoeff, (Size-1)*NumTraits<Scalar>::AddCost);
|
||||||
|
EIGEN_MEMBER_FUNCTOR(maxCoeff, (Size-1)*NumTraits<Scalar>::AddCost);
|
||||||
EIGEN_MEMBER_FUNCTOR(all, (Size-1)*NumTraits<Scalar>::AddCost);
|
EIGEN_MEMBER_FUNCTOR(all, (Size-1)*NumTraits<Scalar>::AddCost);
|
||||||
EIGEN_MEMBER_FUNCTOR(any, (Size-1)*NumTraits<Scalar>::AddCost);
|
EIGEN_MEMBER_FUNCTOR(any, (Size-1)*NumTraits<Scalar>::AddCost);
|
||||||
EIGEN_MEMBER_FUNCTOR(count, (Size-1)*NumTraits<Scalar>::AddCost);
|
EIGEN_MEMBER_FUNCTOR(count, (Size-1)*NumTraits<Scalar>::AddCost);
|
||||||
|
EIGEN_MEMBER_FUNCTOR(prod, (Size-1)*NumTraits<Scalar>::MulCost);
|
||||||
|
|
||||||
EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(sum, (Size-1)*NumTraits<Scalar>::AddCost, 1, internal::scalar_sum_op);
|
template <int p, typename ResultType>
|
||||||
EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(minCoeff, (Size-1)*NumTraits<Scalar>::AddCost, 1, internal::scalar_min_op);
|
|
||||||
EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(maxCoeff, (Size-1)*NumTraits<Scalar>::AddCost, 1, internal::scalar_max_op);
|
|
||||||
EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(prod, (Size-1)*NumTraits<Scalar>::MulCost, 1, internal::scalar_product_op);
|
|
||||||
|
|
||||||
template <int p, typename ResultType,typename Scalar>
|
|
||||||
struct member_lpnorm {
|
struct member_lpnorm {
|
||||||
typedef ResultType result_type;
|
typedef ResultType result_type;
|
||||||
enum { Vectorizable = 0 };
|
template<typename Scalar, int Size> struct Cost
|
||||||
template<int Size> struct Cost
|
|
||||||
{ enum { value = (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost }; };
|
{ enum { value = (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost }; };
|
||||||
EIGEN_DEVICE_FUNC member_lpnorm() {}
|
EIGEN_DEVICE_FUNC member_lpnorm() {}
|
||||||
template<typename XprType>
|
template<typename XprType>
|
||||||
@@ -128,20 +121,17 @@ struct member_lpnorm {
|
|||||||
{ return mat.template lpNorm<p>(); }
|
{ return mat.template lpNorm<p>(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename BinaryOpT, typename Scalar>
|
template <typename BinaryOp, typename Scalar>
|
||||||
struct member_redux {
|
struct member_redux {
|
||||||
typedef BinaryOpT BinaryOp;
|
|
||||||
typedef typename result_of<
|
typedef typename result_of<
|
||||||
BinaryOp(const Scalar&,const Scalar&)
|
BinaryOp(const Scalar&,const Scalar&)
|
||||||
>::type result_type;
|
>::type result_type;
|
||||||
|
template<typename _Scalar, int Size> struct Cost
|
||||||
enum { Vectorizable = functor_traits<BinaryOp>::PacketAccess };
|
{ enum { value = (Size-1) * functor_traits<BinaryOp>::Cost }; };
|
||||||
template<int Size> struct Cost { enum { value = (Size-1) * functor_traits<BinaryOp>::Cost }; };
|
|
||||||
EIGEN_DEVICE_FUNC explicit member_redux(const BinaryOp func) : m_functor(func) {}
|
EIGEN_DEVICE_FUNC explicit member_redux(const BinaryOp func) : m_functor(func) {}
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC 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); }
|
{ return mat.redux(m_functor); }
|
||||||
const BinaryOp& binaryFunc() const { return m_functor; }
|
|
||||||
const BinaryOp m_functor;
|
const BinaryOp m_functor;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -149,38 +139,18 @@ struct member_redux {
|
|||||||
/** \class VectorwiseOp
|
/** \class VectorwiseOp
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
*
|
*
|
||||||
* \brief Pseudo expression providing broadcasting and partial reduction operations
|
* \brief Pseudo expression providing partial reduction operations
|
||||||
*
|
*
|
||||||
* \tparam ExpressionType the type of the object on which to do partial reductions
|
* \tparam ExpressionType the type of the object on which to do partial reductions
|
||||||
* \tparam Direction indicates whether to operate on columns (#Vertical) or rows (#Horizontal)
|
* \tparam Direction indicates the direction of the redux (#Vertical or #Horizontal)
|
||||||
*
|
*
|
||||||
* This class represents a pseudo expression with broadcasting and partial reduction features.
|
* This class represents a pseudo expression with partial reduction features.
|
||||||
* It is the return type of DenseBase::colwise() and DenseBase::rowwise()
|
* It is the return type of DenseBase::colwise() and DenseBase::rowwise()
|
||||||
* and most of the time this is the only way it is explicitly used.
|
* and most of the time this is the only way it is used.
|
||||||
*
|
|
||||||
* To understand the logic of rowwise/colwise expression, let's consider a generic case `A.colwise().foo()`
|
|
||||||
* where `foo` is any method of `VectorwiseOp`. This expression is equivalent to applying `foo()` to each
|
|
||||||
* column of `A` and then re-assemble the outputs in a matrix expression:
|
|
||||||
* \code [A.col(0).foo(), A.col(1).foo(), ..., A.col(A.cols()-1).foo()] \endcode
|
|
||||||
*
|
*
|
||||||
* Example: \include MatrixBase_colwise.cpp
|
* Example: \include MatrixBase_colwise.cpp
|
||||||
* Output: \verbinclude MatrixBase_colwise.out
|
* Output: \verbinclude MatrixBase_colwise.out
|
||||||
*
|
*
|
||||||
* The begin() and end() methods are obviously exceptions to the previous rule as they
|
|
||||||
* return STL-compatible begin/end iterators to the rows or columns of the nested expression.
|
|
||||||
* Typical use cases include for-range-loop and calls to STL algorithms:
|
|
||||||
*
|
|
||||||
* Example: \include MatrixBase_colwise_iterator_cxx11.cpp
|
|
||||||
* Output: \verbinclude MatrixBase_colwise_iterator_cxx11.out
|
|
||||||
*
|
|
||||||
* For a partial reduction on an empty input, some rules apply.
|
|
||||||
* For the sake of clarity, let's consider a vertical reduction:
|
|
||||||
* - If the number of columns is zero, then a 1x0 row-major vector expression is returned.
|
|
||||||
* - Otherwise, if the number of rows is zero, then
|
|
||||||
* - a row vector of zeros is returned for sum-like reductions (sum, squaredNorm, norm, etc.)
|
|
||||||
* - a row vector of ones is returned for a product reduction (e.g., <code>MatrixXd(n,0).colwise().prod()</code>)
|
|
||||||
* - an assert is triggered for all other reductions (minCoeff,maxCoeff,redux(bin_op))
|
|
||||||
*
|
|
||||||
* \sa DenseBase::colwise(), DenseBase::rowwise(), class PartialReduxExpr
|
* \sa DenseBase::colwise(), DenseBase::rowwise(), class PartialReduxExpr
|
||||||
*/
|
*/
|
||||||
template<typename ExpressionType, int Direction> class VectorwiseOp
|
template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||||
@@ -193,11 +163,11 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
|||||||
typedef typename internal::ref_selector<ExpressionType>::non_const_type ExpressionTypeNested;
|
typedef typename internal::ref_selector<ExpressionType>::non_const_type ExpressionTypeNested;
|
||||||
typedef typename internal::remove_all<ExpressionTypeNested>::type ExpressionTypeNestedCleaned;
|
typedef typename internal::remove_all<ExpressionTypeNested>::type ExpressionTypeNestedCleaned;
|
||||||
|
|
||||||
template<template<typename OutScalar,typename InputScalar> class Functor,
|
template<template<typename _Scalar> class Functor,
|
||||||
typename ReturnScalar=Scalar> struct ReturnType
|
typename Scalar_=Scalar> struct ReturnType
|
||||||
{
|
{
|
||||||
typedef PartialReduxExpr<ExpressionType,
|
typedef PartialReduxExpr<ExpressionType,
|
||||||
Functor<ReturnScalar,Scalar>,
|
Functor<Scalar_>,
|
||||||
Direction
|
Direction
|
||||||
> Type;
|
> Type;
|
||||||
};
|
};
|
||||||
@@ -217,6 +187,23 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
typedef typename internal::conditional<isVertical,
|
||||||
|
typename ExpressionType::ColXpr,
|
||||||
|
typename ExpressionType::RowXpr>::type SubVector;
|
||||||
|
/** \internal
|
||||||
|
* \returns the i-th subvector according to the \c Direction */
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
SubVector subVector(Index i)
|
||||||
|
{
|
||||||
|
return SubVector(m_matrix.derived(),i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \internal
|
||||||
|
* \returns the number of subvectors in the direction \c Direction */
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
Index subVectors() const
|
||||||
|
{ return isVertical?m_matrix.cols():m_matrix.rows(); }
|
||||||
|
|
||||||
template<typename OtherDerived> struct ExtendedType {
|
template<typename OtherDerived> struct ExtendedType {
|
||||||
typedef Replicate<OtherDerived,
|
typedef Replicate<OtherDerived,
|
||||||
isVertical ? 1 : ExpressionType::RowsAtCompileTime,
|
isVertical ? 1 : ExpressionType::RowsAtCompileTime,
|
||||||
@@ -271,101 +258,42 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline const ExpressionType& _expression() const { return m_matrix; }
|
inline const ExpressionType& _expression() const { return m_matrix; }
|
||||||
|
|
||||||
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
/** STL-like <a href="https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator">RandomAccessIterator</a>
|
|
||||||
* iterator type over the columns or rows as returned by the begin() and end() methods.
|
|
||||||
*/
|
|
||||||
random_access_iterator_type iterator;
|
|
||||||
/** This is the const version of iterator (aka read-only) */
|
|
||||||
random_access_iterator_type const_iterator;
|
|
||||||
#else
|
|
||||||
typedef internal::subvector_stl_iterator<ExpressionType, DirectionType(Direction)> iterator;
|
|
||||||
typedef internal::subvector_stl_iterator<const ExpressionType, DirectionType(Direction)> const_iterator;
|
|
||||||
typedef internal::subvector_stl_reverse_iterator<ExpressionType, DirectionType(Direction)> reverse_iterator;
|
|
||||||
typedef internal::subvector_stl_reverse_iterator<const ExpressionType, DirectionType(Direction)> const_reverse_iterator;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** returns an iterator to the first row (rowwise) or column (colwise) of the nested expression.
|
|
||||||
* \sa end(), cbegin()
|
|
||||||
*/
|
|
||||||
iterator begin() { return iterator (m_matrix, 0); }
|
|
||||||
/** const version of begin() */
|
|
||||||
const_iterator begin() const { return const_iterator(m_matrix, 0); }
|
|
||||||
/** const version of begin() */
|
|
||||||
const_iterator cbegin() const { return const_iterator(m_matrix, 0); }
|
|
||||||
|
|
||||||
/** returns a reverse iterator to the last row (rowwise) or column (colwise) of the nested expression.
|
|
||||||
* \sa rend(), crbegin()
|
|
||||||
*/
|
|
||||||
reverse_iterator rbegin() { return reverse_iterator (m_matrix, m_matrix.template subVectors<DirectionType(Direction)>()-1); }
|
|
||||||
/** const version of rbegin() */
|
|
||||||
const_reverse_iterator rbegin() const { return const_reverse_iterator (m_matrix, m_matrix.template subVectors<DirectionType(Direction)>()-1); }
|
|
||||||
/** const version of rbegin() */
|
|
||||||
const_reverse_iterator crbegin() const { return const_reverse_iterator (m_matrix, m_matrix.template subVectors<DirectionType(Direction)>()-1); }
|
|
||||||
|
|
||||||
/** returns an iterator to the row (resp. column) following the last row (resp. column) of the nested expression
|
|
||||||
* \sa begin(), cend()
|
|
||||||
*/
|
|
||||||
iterator end() { return iterator (m_matrix, m_matrix.template subVectors<DirectionType(Direction)>()); }
|
|
||||||
/** const version of end() */
|
|
||||||
const_iterator end() const { return const_iterator(m_matrix, m_matrix.template subVectors<DirectionType(Direction)>()); }
|
|
||||||
/** const version of end() */
|
|
||||||
const_iterator cend() const { return const_iterator(m_matrix, m_matrix.template subVectors<DirectionType(Direction)>()); }
|
|
||||||
|
|
||||||
/** returns a reverse iterator to the row (resp. column) before the first row (resp. column) of the nested expression
|
|
||||||
* \sa begin(), cend()
|
|
||||||
*/
|
|
||||||
reverse_iterator rend() { return reverse_iterator (m_matrix, -1); }
|
|
||||||
/** const version of rend() */
|
|
||||||
const_reverse_iterator rend() const { return const_reverse_iterator (m_matrix, -1); }
|
|
||||||
/** const version of rend() */
|
|
||||||
const_reverse_iterator crend() const { return const_reverse_iterator (m_matrix, -1); }
|
|
||||||
|
|
||||||
/** \returns a row or column vector expression of \c *this reduxed by \a func
|
/** \returns a row or column vector expression of \c *this reduxed by \a func
|
||||||
*
|
*
|
||||||
* The template parameter \a BinaryOp is the type of the functor
|
* The template parameter \a BinaryOp is the type of the functor
|
||||||
* of the custom redux operator. Note that func must be an associative operator.
|
* of the custom redux operator. Note that func must be an associative operator.
|
||||||
*
|
*
|
||||||
* \warning the size along the reduction direction must be strictly positive,
|
|
||||||
* otherwise an assertion is triggered.
|
|
||||||
*
|
|
||||||
* \sa class VectorwiseOp, DenseBase::colwise(), DenseBase::rowwise()
|
* \sa class VectorwiseOp, DenseBase::colwise(), DenseBase::rowwise()
|
||||||
*/
|
*/
|
||||||
template<typename BinaryOp>
|
template<typename BinaryOp>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const typename ReduxReturnType<BinaryOp>::Type
|
const typename ReduxReturnType<BinaryOp>::Type
|
||||||
redux(const BinaryOp& func = BinaryOp()) const
|
redux(const BinaryOp& func = BinaryOp()) const
|
||||||
{
|
{ return typename ReduxReturnType<BinaryOp>::Type(_expression(), internal::member_redux<BinaryOp,Scalar>(func)); }
|
||||||
eigen_assert(redux_length()>0 && "you are using an empty matrix");
|
|
||||||
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_minCoeff>::Type MinCoeffReturnType;
|
||||||
typedef typename ReturnType<internal::member_maxCoeff>::Type MaxCoeffReturnType;
|
typedef typename ReturnType<internal::member_maxCoeff>::Type MaxCoeffReturnType;
|
||||||
typedef PartialReduxExpr<const CwiseUnaryOp<internal::scalar_abs2_op<Scalar>, const ExpressionTypeNestedCleaned>,internal::member_sum<RealScalar,RealScalar>,Direction> SquaredNormReturnType;
|
typedef typename ReturnType<internal::member_squaredNorm,RealScalar>::Type SquaredNormReturnType;
|
||||||
typedef CwiseUnaryOp<internal::scalar_sqrt_op<RealScalar>, const SquaredNormReturnType> NormReturnType;
|
typedef typename ReturnType<internal::member_norm,RealScalar>::Type NormReturnType;
|
||||||
typedef typename ReturnType<internal::member_blueNorm,RealScalar>::Type BlueNormReturnType;
|
typedef typename ReturnType<internal::member_blueNorm,RealScalar>::Type BlueNormReturnType;
|
||||||
typedef typename ReturnType<internal::member_stableNorm,RealScalar>::Type StableNormReturnType;
|
typedef typename ReturnType<internal::member_stableNorm,RealScalar>::Type StableNormReturnType;
|
||||||
typedef typename ReturnType<internal::member_hypotNorm,RealScalar>::Type HypotNormReturnType;
|
typedef typename ReturnType<internal::member_hypotNorm,RealScalar>::Type HypotNormReturnType;
|
||||||
typedef typename ReturnType<internal::member_sum>::Type SumReturnType;
|
typedef typename ReturnType<internal::member_sum>::Type SumReturnType;
|
||||||
typedef EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(SumReturnType,Scalar,quotient) MeanReturnType;
|
typedef typename ReturnType<internal::member_mean>::Type MeanReturnType;
|
||||||
typedef typename ReturnType<internal::member_all>::Type AllReturnType;
|
typedef typename ReturnType<internal::member_all>::Type AllReturnType;
|
||||||
typedef typename ReturnType<internal::member_any>::Type AnyReturnType;
|
typedef typename ReturnType<internal::member_any>::Type AnyReturnType;
|
||||||
typedef PartialReduxExpr<ExpressionType, internal::member_count<Index,Scalar>, Direction> CountReturnType;
|
typedef PartialReduxExpr<ExpressionType, internal::member_count<Index>, Direction> CountReturnType;
|
||||||
typedef typename ReturnType<internal::member_prod>::Type ProdReturnType;
|
typedef typename ReturnType<internal::member_prod>::Type ProdReturnType;
|
||||||
typedef Reverse<const ExpressionType, Direction> ConstReverseReturnType;
|
typedef Reverse<const ExpressionType, Direction> ConstReverseReturnType;
|
||||||
typedef Reverse<ExpressionType, Direction> ReverseReturnType;
|
typedef Reverse<ExpressionType, Direction> ReverseReturnType;
|
||||||
|
|
||||||
template<int p> struct LpNormReturnType {
|
template<int p> struct LpNormReturnType {
|
||||||
typedef PartialReduxExpr<ExpressionType, internal::member_lpnorm<p,RealScalar,Scalar>,Direction> Type;
|
typedef PartialReduxExpr<ExpressionType, internal::member_lpnorm<p,RealScalar>,Direction> Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \returns a row (or column) vector expression of the smallest coefficient
|
/** \returns a row (or column) vector expression of the smallest coefficient
|
||||||
* of each column (or row) of the referenced expression.
|
* of each column (or row) of the referenced expression.
|
||||||
*
|
*
|
||||||
* \warning the size along the reduction direction must be strictly positive,
|
|
||||||
* otherwise an assertion is triggered.
|
|
||||||
*
|
|
||||||
* \warning the result is undefined if \c *this contains NaN.
|
* \warning the result is undefined if \c *this contains NaN.
|
||||||
*
|
*
|
||||||
* Example: \include PartialRedux_minCoeff.cpp
|
* Example: \include PartialRedux_minCoeff.cpp
|
||||||
@@ -374,17 +302,11 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
|||||||
* \sa DenseBase::minCoeff() */
|
* \sa DenseBase::minCoeff() */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const MinCoeffReturnType minCoeff() const
|
const MinCoeffReturnType minCoeff() const
|
||||||
{
|
{ return MinCoeffReturnType(_expression()); }
|
||||||
eigen_assert(redux_length()>0 && "you are using an empty matrix");
|
|
||||||
return MinCoeffReturnType(_expression());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \returns a row (or column) vector expression of the largest coefficient
|
/** \returns a row (or column) vector expression of the largest coefficient
|
||||||
* of each column (or row) of the referenced expression.
|
* of each column (or row) of the referenced expression.
|
||||||
*
|
*
|
||||||
* \warning the size along the reduction direction must be strictly positive,
|
|
||||||
* otherwise an assertion is triggered.
|
|
||||||
*
|
|
||||||
* \warning the result is undefined if \c *this contains NaN.
|
* \warning the result is undefined if \c *this contains NaN.
|
||||||
*
|
*
|
||||||
* Example: \include PartialRedux_maxCoeff.cpp
|
* Example: \include PartialRedux_maxCoeff.cpp
|
||||||
@@ -393,10 +315,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
|||||||
* \sa DenseBase::maxCoeff() */
|
* \sa DenseBase::maxCoeff() */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const MaxCoeffReturnType maxCoeff() const
|
const MaxCoeffReturnType maxCoeff() const
|
||||||
{
|
{ return MaxCoeffReturnType(_expression()); }
|
||||||
eigen_assert(redux_length()>0 && "you are using an empty matrix");
|
|
||||||
return MaxCoeffReturnType(_expression());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \returns a row (or column) vector expression of the squared norm
|
/** \returns a row (or column) vector expression of the squared norm
|
||||||
* of each column (or row) of the referenced expression.
|
* of each column (or row) of the referenced expression.
|
||||||
@@ -408,7 +327,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
|||||||
* \sa DenseBase::squaredNorm() */
|
* \sa DenseBase::squaredNorm() */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const SquaredNormReturnType squaredNorm() const
|
const SquaredNormReturnType squaredNorm() const
|
||||||
{ return SquaredNormReturnType(m_matrix.cwiseAbs2()); }
|
{ return SquaredNormReturnType(_expression()); }
|
||||||
|
|
||||||
/** \returns a row (or column) vector expression of the norm
|
/** \returns a row (or column) vector expression of the norm
|
||||||
* of each column (or row) of the referenced expression.
|
* of each column (or row) of the referenced expression.
|
||||||
@@ -420,7 +339,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
|||||||
* \sa DenseBase::norm() */
|
* \sa DenseBase::norm() */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const NormReturnType norm() const
|
const NormReturnType norm() const
|
||||||
{ return NormReturnType(squaredNorm()); }
|
{ return NormReturnType(_expression()); }
|
||||||
|
|
||||||
/** \returns a row (or column) vector expression of the norm
|
/** \returns a row (or column) vector expression of the norm
|
||||||
* of each column (or row) of the referenced expression.
|
* of each column (or row) of the referenced expression.
|
||||||
@@ -485,7 +404,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
|||||||
* \sa DenseBase::mean() */
|
* \sa DenseBase::mean() */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const MeanReturnType mean() const
|
const MeanReturnType mean() const
|
||||||
{ return sum() / Scalar(Direction==Vertical?m_matrix.rows():m_matrix.cols()); }
|
{ return MeanReturnType(_expression()); }
|
||||||
|
|
||||||
/** \returns a row (or column) vector expression representing
|
/** \returns a row (or column) vector expression representing
|
||||||
* whether \b all coefficients of each respective column (or row) are \c true.
|
* whether \b all coefficients of each respective column (or row) are \c true.
|
||||||
@@ -581,7 +500,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
|||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
|
||||||
EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
|
EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
|
||||||
//eigen_assert((m_matrix.isNull()) == (other.isNull())); FIXME
|
//eigen_assert((m_matrix.isNull()) == (other.isNull())); FIXME
|
||||||
return m_matrix = extendedTo(other.derived());
|
return const_cast<ExpressionType&>(m_matrix = extendedTo(other.derived()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds the vector \a other to each subvector of \c *this */
|
/** Adds the vector \a other to each subvector of \c *this */
|
||||||
@@ -591,7 +510,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
|||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
|
||||||
EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
|
EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
|
||||||
return m_matrix += extendedTo(other.derived());
|
return const_cast<ExpressionType&>(m_matrix += extendedTo(other.derived()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Substracts the vector \a other to each subvector of \c *this */
|
/** Substracts the vector \a other to each subvector of \c *this */
|
||||||
@@ -601,7 +520,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
|||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
|
||||||
EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
|
EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
|
||||||
return m_matrix -= extendedTo(other.derived());
|
return const_cast<ExpressionType&>(m_matrix -= extendedTo(other.derived()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Multiples each subvector of \c *this by the vector \a other */
|
/** Multiples each subvector of \c *this by the vector \a other */
|
||||||
@@ -613,7 +532,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
|||||||
EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
|
EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
|
||||||
EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
|
EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
|
||||||
m_matrix *= extendedTo(other.derived());
|
m_matrix *= extendedTo(other.derived());
|
||||||
return m_matrix;
|
return const_cast<ExpressionType&>(m_matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Divides each subvector of \c *this by the vector \a other */
|
/** Divides each subvector of \c *this by the vector \a other */
|
||||||
@@ -625,7 +544,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
|||||||
EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
|
EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
|
||||||
EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
|
EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
|
||||||
m_matrix /= extendedTo(other.derived());
|
m_matrix /= extendedTo(other.derived());
|
||||||
return m_matrix;
|
return const_cast<ExpressionType&>(m_matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the expression of the sum of the vector \a other to each subvector of \c *this */
|
/** Returns the expression of the sum of the vector \a other to each subvector of \c *this */
|
||||||
@@ -690,7 +609,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
CwiseBinaryOp<internal::scalar_quotient_op<Scalar>,
|
CwiseBinaryOp<internal::scalar_quotient_op<Scalar>,
|
||||||
const ExpressionTypeNestedCleaned,
|
const ExpressionTypeNestedCleaned,
|
||||||
const typename OppositeExtendedType<NormReturnType>::Type>
|
const typename OppositeExtendedType<typename ReturnType<internal::member_norm,RealScalar>::Type>::Type>
|
||||||
normalized() const { return m_matrix.cwiseQuotient(extendedToOpposite(this->norm())); }
|
normalized() const { return m_matrix.cwiseQuotient(extendedToOpposite(this->norm())); }
|
||||||
|
|
||||||
|
|
||||||
@@ -739,15 +658,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const HNormalizedReturnType hnormalized() const;
|
const HNormalizedReturnType hnormalized() const;
|
||||||
|
|
||||||
# ifdef EIGEN_VECTORWISEOP_PLUGIN
|
|
||||||
# include EIGEN_VECTORWISEOP_PLUGIN
|
|
||||||
# endif
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Index redux_length() const
|
|
||||||
{
|
|
||||||
return Direction==Vertical ? m_matrix.rows() : m_matrix.cols();
|
|
||||||
}
|
|
||||||
ExpressionTypeNested m_matrix;
|
ExpressionTypeNested m_matrix;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -40,14 +40,6 @@ struct visitor_impl<Visitor, Derived, 1>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// This specialization enables visitors on empty matrices at compile-time
|
|
||||||
template<typename Visitor, typename Derived>
|
|
||||||
struct visitor_impl<Visitor, Derived, 0> {
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static inline void run(const Derived &/*mat*/, Visitor& /*visitor*/)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Visitor, typename Derived>
|
template<typename Visitor, typename Derived>
|
||||||
struct visitor_impl<Visitor, Derived, Dynamic>
|
struct visitor_impl<Visitor, Derived, Dynamic>
|
||||||
{
|
{
|
||||||
@@ -79,9 +71,9 @@ public:
|
|||||||
CoeffReadCost = internal::evaluator<XprType>::CoeffReadCost
|
CoeffReadCost = internal::evaluator<XprType>::CoeffReadCost
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_xpr.rows(); }
|
EIGEN_DEVICE_FUNC Index rows() const { return m_xpr.rows(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_xpr.cols(); }
|
EIGEN_DEVICE_FUNC Index cols() const { return m_xpr.cols(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index size() const EIGEN_NOEXCEPT { return m_xpr.size(); }
|
EIGEN_DEVICE_FUNC Index size() const { return m_xpr.size(); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC CoeffReturnType coeff(Index row, Index col) const
|
EIGEN_DEVICE_FUNC CoeffReturnType coeff(Index row, Index col) const
|
||||||
{ return m_evaluator.coeff(row, col); }
|
{ return m_evaluator.coeff(row, col); }
|
||||||
@@ -107,8 +99,6 @@ protected:
|
|||||||
* \note compared to one or two \em for \em loops, visitors offer automatic
|
* \note compared to one or two \em for \em loops, visitors offer automatic
|
||||||
* unrolling for small fixed size matrix.
|
* unrolling for small fixed size matrix.
|
||||||
*
|
*
|
||||||
* \note if the matrix is empty, then the visitor is left unchanged.
|
|
||||||
*
|
|
||||||
* \sa minCoeff(Index*,Index*), maxCoeff(Index*,Index*), DenseBase::redux()
|
* \sa minCoeff(Index*,Index*), maxCoeff(Index*,Index*), DenseBase::redux()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
@@ -116,15 +106,12 @@ template<typename Visitor>
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
void DenseBase<Derived>::visit(Visitor& visitor) const
|
void DenseBase<Derived>::visit(Visitor& visitor) const
|
||||||
{
|
{
|
||||||
if(size()==0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
typedef typename internal::visitor_evaluator<Derived> ThisEvaluator;
|
typedef typename internal::visitor_evaluator<Derived> ThisEvaluator;
|
||||||
ThisEvaluator thisEval(derived());
|
ThisEvaluator thisEval(derived());
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
unroll = SizeAtCompileTime != Dynamic
|
unroll = SizeAtCompileTime != Dynamic
|
||||||
&& SizeAtCompileTime * int(ThisEvaluator::CoeffReadCost) + (SizeAtCompileTime-1) * int(internal::functor_traits<Visitor>::Cost) <= EIGEN_UNROLLING_LIMIT
|
&& SizeAtCompileTime * ThisEvaluator::CoeffReadCost + (SizeAtCompileTime-1) * internal::functor_traits<Visitor>::Cost <= EIGEN_UNROLLING_LIMIT
|
||||||
};
|
};
|
||||||
return internal::visitor_impl<Visitor, ThisEvaluator, unroll ? int(SizeAtCompileTime) : Dynamic>::run(thisEval, visitor);
|
return internal::visitor_impl<Visitor, ThisEvaluator, unroll ? int(SizeAtCompileTime) : Dynamic>::run(thisEval, visitor);
|
||||||
}
|
}
|
||||||
@@ -137,9 +124,6 @@ namespace internal {
|
|||||||
template <typename Derived>
|
template <typename Derived>
|
||||||
struct coeff_visitor
|
struct coeff_visitor
|
||||||
{
|
{
|
||||||
// default initialization to avoid countless invalid maybe-uninitialized warnings by gcc
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
coeff_visitor() : row(-1), col(-1), res(0) {}
|
|
||||||
typedef typename Derived::Scalar Scalar;
|
typedef typename Derived::Scalar Scalar;
|
||||||
Index row, col;
|
Index row, col;
|
||||||
Scalar res;
|
Scalar res;
|
||||||
@@ -157,7 +141,7 @@ struct coeff_visitor
|
|||||||
*
|
*
|
||||||
* \sa DenseBase::minCoeff(Index*, Index*)
|
* \sa DenseBase::minCoeff(Index*, Index*)
|
||||||
*/
|
*/
|
||||||
template <typename Derived, int NaNPropagation>
|
template <typename Derived>
|
||||||
struct min_coeff_visitor : coeff_visitor<Derived>
|
struct min_coeff_visitor : coeff_visitor<Derived>
|
||||||
{
|
{
|
||||||
typedef typename Derived::Scalar Scalar;
|
typedef typename Derived::Scalar Scalar;
|
||||||
@@ -173,40 +157,8 @@ struct min_coeff_visitor : coeff_visitor<Derived>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Derived>
|
template<typename Scalar>
|
||||||
struct min_coeff_visitor<Derived, PropagateNumbers> : coeff_visitor<Derived>
|
struct functor_traits<min_coeff_visitor<Scalar> > {
|
||||||
{
|
|
||||||
typedef typename Derived::Scalar Scalar;
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
void operator() (const Scalar& value, Index i, Index j)
|
|
||||||
{
|
|
||||||
if((numext::isnan)(this->res) || (!(numext::isnan)(value) && value < this->res))
|
|
||||||
{
|
|
||||||
this->res = value;
|
|
||||||
this->row = i;
|
|
||||||
this->col = j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Derived>
|
|
||||||
struct min_coeff_visitor<Derived, PropagateNaN> : coeff_visitor<Derived>
|
|
||||||
{
|
|
||||||
typedef typename Derived::Scalar Scalar;
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
void operator() (const Scalar& value, Index i, Index j)
|
|
||||||
{
|
|
||||||
if((numext::isnan)(value) || value < this->res)
|
|
||||||
{
|
|
||||||
this->res = value;
|
|
||||||
this->row = i;
|
|
||||||
this->col = j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Scalar, int NaNPropagation>
|
|
||||||
struct functor_traits<min_coeff_visitor<Scalar, NaNPropagation> > {
|
|
||||||
enum {
|
enum {
|
||||||
Cost = NumTraits<Scalar>::AddCost
|
Cost = NumTraits<Scalar>::AddCost
|
||||||
};
|
};
|
||||||
@@ -217,7 +169,7 @@ template<typename Scalar, int NaNPropagation>
|
|||||||
*
|
*
|
||||||
* \sa DenseBase::maxCoeff(Index*, Index*)
|
* \sa DenseBase::maxCoeff(Index*, Index*)
|
||||||
*/
|
*/
|
||||||
template <typename Derived, int NaNPropagation>
|
template <typename Derived>
|
||||||
struct max_coeff_visitor : coeff_visitor<Derived>
|
struct max_coeff_visitor : coeff_visitor<Derived>
|
||||||
{
|
{
|
||||||
typedef typename Derived::Scalar Scalar;
|
typedef typename Derived::Scalar Scalar;
|
||||||
@@ -233,40 +185,8 @@ struct max_coeff_visitor : coeff_visitor<Derived>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Derived>
|
template<typename Scalar>
|
||||||
struct max_coeff_visitor<Derived, PropagateNumbers> : coeff_visitor<Derived>
|
struct functor_traits<max_coeff_visitor<Scalar> > {
|
||||||
{
|
|
||||||
typedef typename Derived::Scalar Scalar;
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
void operator() (const Scalar& value, Index i, Index j)
|
|
||||||
{
|
|
||||||
if((numext::isnan)(this->res) || (!(numext::isnan)(value) && value > this->res))
|
|
||||||
{
|
|
||||||
this->res = value;
|
|
||||||
this->row = i;
|
|
||||||
this->col = j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Derived>
|
|
||||||
struct max_coeff_visitor<Derived, PropagateNaN> : coeff_visitor<Derived>
|
|
||||||
{
|
|
||||||
typedef typename Derived::Scalar Scalar;
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
void operator() (const Scalar& value, Index i, Index j)
|
|
||||||
{
|
|
||||||
if((numext::isnan)(value) || value > this->res)
|
|
||||||
{
|
|
||||||
this->res = value;
|
|
||||||
this->row = i;
|
|
||||||
this->col = j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Scalar, int NaNPropagation>
|
|
||||||
struct functor_traits<max_coeff_visitor<Scalar, NaNPropagation> > {
|
|
||||||
enum {
|
enum {
|
||||||
Cost = NumTraits<Scalar>::AddCost
|
Cost = NumTraits<Scalar>::AddCost
|
||||||
};
|
};
|
||||||
@@ -276,24 +196,17 @@ struct functor_traits<max_coeff_visitor<Scalar, NaNPropagation> > {
|
|||||||
|
|
||||||
/** \fn DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
|
/** \fn DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
|
||||||
* \returns the minimum of all coefficients of *this and puts in *row and *col its location.
|
* \returns the minimum of all coefficients of *this and puts in *row and *col its location.
|
||||||
*
|
* \warning the result is undefined if \c *this contains NaN.
|
||||||
* In case \c *this contains NaN, NaNPropagation determines the behavior:
|
|
||||||
* NaNPropagation == PropagateFast : undefined
|
|
||||||
* NaNPropagation == PropagateNaN : result is NaN
|
|
||||||
* NaNPropagation == PropagateNumbers : result is maximum of elements that are not NaN
|
|
||||||
* \warning the matrix must be not empty, otherwise an assertion is triggered.
|
|
||||||
*
|
*
|
||||||
* \sa DenseBase::minCoeff(Index*), DenseBase::maxCoeff(Index*,Index*), DenseBase::visit(), DenseBase::minCoeff()
|
* \sa DenseBase::minCoeff(Index*), DenseBase::maxCoeff(Index*,Index*), DenseBase::visit(), DenseBase::minCoeff()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<int NaNPropagation, typename IndexType>
|
template<typename IndexType>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
typename internal::traits<Derived>::Scalar
|
typename internal::traits<Derived>::Scalar
|
||||||
DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
|
DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
|
||||||
{
|
{
|
||||||
eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
|
internal::min_coeff_visitor<Derived> minVisitor;
|
||||||
|
|
||||||
internal::min_coeff_visitor<Derived, NaNPropagation> minVisitor;
|
|
||||||
this->visit(minVisitor);
|
this->visit(minVisitor);
|
||||||
*rowId = minVisitor.row;
|
*rowId = minVisitor.row;
|
||||||
if (colId) *colId = minVisitor.col;
|
if (colId) *colId = minVisitor.col;
|
||||||
@@ -301,25 +214,18 @@ DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the minimum of all coefficients of *this and puts in *index its location.
|
/** \returns the minimum of all coefficients of *this and puts in *index its location.
|
||||||
*
|
* \warning the result is undefined if \c *this contains NaN.
|
||||||
* In case \c *this contains NaN, NaNPropagation determines the behavior:
|
|
||||||
* NaNPropagation == PropagateFast : undefined
|
|
||||||
* NaNPropagation == PropagateNaN : result is NaN
|
|
||||||
* NaNPropagation == PropagateNumbers : result is maximum of elements that are not NaN
|
|
||||||
* \warning the matrix must be not empty, otherwise an assertion is triggered.
|
|
||||||
*
|
*
|
||||||
* \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::visit(), DenseBase::minCoeff()
|
* \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::visit(), DenseBase::minCoeff()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<int NaNPropagation, typename IndexType>
|
template<typename IndexType>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
typename internal::traits<Derived>::Scalar
|
typename internal::traits<Derived>::Scalar
|
||||||
DenseBase<Derived>::minCoeff(IndexType* index) const
|
DenseBase<Derived>::minCoeff(IndexType* index) const
|
||||||
{
|
{
|
||||||
eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
|
|
||||||
|
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
internal::min_coeff_visitor<Derived, NaNPropagation> minVisitor;
|
internal::min_coeff_visitor<Derived> minVisitor;
|
||||||
this->visit(minVisitor);
|
this->visit(minVisitor);
|
||||||
*index = IndexType((RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row);
|
*index = IndexType((RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row);
|
||||||
return minVisitor.res;
|
return minVisitor.res;
|
||||||
@@ -327,24 +233,17 @@ DenseBase<Derived>::minCoeff(IndexType* index) const
|
|||||||
|
|
||||||
/** \fn DenseBase<Derived>::maxCoeff(IndexType* rowId, IndexType* colId) const
|
/** \fn DenseBase<Derived>::maxCoeff(IndexType* rowId, IndexType* colId) const
|
||||||
* \returns the maximum of all coefficients of *this and puts in *row and *col its location.
|
* \returns the maximum of all coefficients of *this and puts in *row and *col its location.
|
||||||
*
|
* \warning the result is undefined if \c *this contains NaN.
|
||||||
* In case \c *this contains NaN, NaNPropagation determines the behavior:
|
|
||||||
* NaNPropagation == PropagateFast : undefined
|
|
||||||
* NaNPropagation == PropagateNaN : result is NaN
|
|
||||||
* NaNPropagation == PropagateNumbers : result is maximum of elements that are not NaN
|
|
||||||
* \warning the matrix must be not empty, otherwise an assertion is triggered.
|
|
||||||
*
|
*
|
||||||
* \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visit(), DenseBase::maxCoeff()
|
* \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visit(), DenseBase::maxCoeff()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<int NaNPropagation, typename IndexType>
|
template<typename IndexType>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
typename internal::traits<Derived>::Scalar
|
typename internal::traits<Derived>::Scalar
|
||||||
DenseBase<Derived>::maxCoeff(IndexType* rowPtr, IndexType* colPtr) const
|
DenseBase<Derived>::maxCoeff(IndexType* rowPtr, IndexType* colPtr) const
|
||||||
{
|
{
|
||||||
eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
|
internal::max_coeff_visitor<Derived> maxVisitor;
|
||||||
|
|
||||||
internal::max_coeff_visitor<Derived, NaNPropagation> maxVisitor;
|
|
||||||
this->visit(maxVisitor);
|
this->visit(maxVisitor);
|
||||||
*rowPtr = maxVisitor.row;
|
*rowPtr = maxVisitor.row;
|
||||||
if (colPtr) *colPtr = maxVisitor.col;
|
if (colPtr) *colPtr = maxVisitor.col;
|
||||||
@@ -352,25 +251,18 @@ DenseBase<Derived>::maxCoeff(IndexType* rowPtr, IndexType* colPtr) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the maximum of all coefficients of *this and puts in *index its location.
|
/** \returns the maximum of all coefficients of *this and puts in *index its location.
|
||||||
*
|
* \warning the result is undefined if \c *this contains NaN.
|
||||||
* In case \c *this contains NaN, NaNPropagation determines the behavior:
|
|
||||||
* NaNPropagation == PropagateFast : undefined
|
|
||||||
* NaNPropagation == PropagateNaN : result is NaN
|
|
||||||
* NaNPropagation == PropagateNumbers : result is maximum of elements that are not NaN
|
|
||||||
* \warning the matrix must be not empty, otherwise an assertion is triggered.
|
|
||||||
*
|
*
|
||||||
* \sa DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visitor(), DenseBase::maxCoeff()
|
* \sa DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visitor(), DenseBase::maxCoeff()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<int NaNPropagation, typename IndexType>
|
template<typename IndexType>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
typename internal::traits<Derived>::Scalar
|
typename internal::traits<Derived>::Scalar
|
||||||
DenseBase<Derived>::maxCoeff(IndexType* index) const
|
DenseBase<Derived>::maxCoeff(IndexType* index) const
|
||||||
{
|
{
|
||||||
eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
|
|
||||||
|
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
internal::max_coeff_visitor<Derived, NaNPropagation> maxVisitor;
|
internal::max_coeff_visitor<Derived> maxVisitor;
|
||||||
this->visit(maxVisitor);
|
this->visit(maxVisitor);
|
||||||
*index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row;
|
*index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row;
|
||||||
return maxVisitor.res;
|
return maxVisitor.res;
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ struct Packet4cf
|
|||||||
__m256 v;
|
__m256 v;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef EIGEN_VECTORIZE_AVX512
|
|
||||||
template<> struct packet_traits<std::complex<float> > : default_packet_traits
|
template<> struct packet_traits<std::complex<float> > : default_packet_traits
|
||||||
{
|
{
|
||||||
typedef Packet4cf type;
|
typedef Packet4cf type;
|
||||||
@@ -38,7 +37,6 @@ template<> struct packet_traits<std::complex<float> > : default_packet_traits
|
|||||||
HasMul = 1,
|
HasMul = 1,
|
||||||
HasDiv = 1,
|
HasDiv = 1,
|
||||||
HasNegate = 1,
|
HasNegate = 1,
|
||||||
HasSqrt = 1,
|
|
||||||
HasAbs = 0,
|
HasAbs = 0,
|
||||||
HasAbs2 = 0,
|
HasAbs2 = 0,
|
||||||
HasMin = 0,
|
HasMin = 0,
|
||||||
@@ -46,20 +44,8 @@ template<> struct packet_traits<std::complex<float> > : default_packet_traits
|
|||||||
HasSetLinear = 0
|
HasSetLinear = 0
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
template<> struct unpacket_traits<Packet4cf> {
|
template<> struct unpacket_traits<Packet4cf> { typedef std::complex<float> type; enum {size=4, alignment=Aligned32}; typedef Packet2cf half; };
|
||||||
typedef std::complex<float> type;
|
|
||||||
typedef Packet2cf half;
|
|
||||||
typedef Packet8f as_real;
|
|
||||||
enum {
|
|
||||||
size=4,
|
|
||||||
alignment=Aligned32,
|
|
||||||
vectorizable=true,
|
|
||||||
masked_load_available=false,
|
|
||||||
masked_store_available=false
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
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 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 psub<Packet4cf>(const Packet4cf& a, const Packet4cf& b) { return Packet4cf(_mm256_sub_ps(a.v,b.v)); }
|
||||||
@@ -81,17 +67,10 @@ template<> EIGEN_STRONG_INLINE Packet4cf pmul<Packet4cf>(const Packet4cf& a, con
|
|||||||
return Packet4cf(result);
|
return Packet4cf(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
|
||||||
EIGEN_STRONG_INLINE Packet4cf pcmp_eq(const Packet4cf& a, const Packet4cf& b) {
|
|
||||||
__m256 eq = _mm256_cmp_ps(a.v, b.v, _CMP_EQ_OQ);
|
|
||||||
return Packet4cf(_mm256_and_ps(eq, _mm256_permute_ps(eq, 0xb1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet4cf ptrue<Packet4cf>(const Packet4cf& a) { return Packet4cf(ptrue(Packet8f(a.v))); }
|
|
||||||
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 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 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 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(b.v,a.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 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 ploadu<Packet4cf>(const std::complex<float>* from) { EIGEN_DEBUG_UNALIGNED_LOAD return Packet4cf(ploadu<Packet8f>(&numext::real_ref(*from))); }
|
||||||
@@ -99,9 +78,7 @@ template<> EIGEN_STRONG_INLINE Packet4cf ploadu<Packet4cf>(const std::complex<fl
|
|||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet4cf pset1<Packet4cf>(const std::complex<float>& from)
|
template<> EIGEN_STRONG_INLINE Packet4cf pset1<Packet4cf>(const std::complex<float>& from)
|
||||||
{
|
{
|
||||||
const float re = std::real(from);
|
return Packet4cf(_mm256_castpd_ps(_mm256_broadcast_sd((const double*)(const void*)&from)));
|
||||||
const float im = std::imag(from);
|
|
||||||
return Packet4cf(_mm256_set_ps(im, re, im, re, im, re, im, re));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet4cf ploaddup<Packet4cf>(const std::complex<float>* from)
|
template<> EIGEN_STRONG_INLINE Packet4cf ploaddup<Packet4cf>(const std::complex<float>* from)
|
||||||
@@ -163,18 +140,79 @@ template<> EIGEN_STRONG_INLINE std::complex<float> predux<Packet4cf>(const Packe
|
|||||||
Packet2cf(_mm256_extractf128_ps(a.v,1))));
|
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)
|
template<> EIGEN_STRONG_INLINE std::complex<float> predux_mul<Packet4cf>(const Packet4cf& a)
|
||||||
{
|
{
|
||||||
return predux_mul(pmul(Packet2cf(_mm256_extractf128_ps(a.v, 0)),
|
return predux_mul(pmul(Packet2cf(_mm256_extractf128_ps(a.v, 0)),
|
||||||
Packet2cf(_mm256_extractf128_ps(a.v, 1))));
|
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));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet4cf,Packet8f)
|
EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet4cf,Packet8f)
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet4cf pdiv<Packet4cf>(const Packet4cf& a, const Packet4cf& b)
|
template<> EIGEN_STRONG_INLINE Packet4cf pdiv<Packet4cf>(const Packet4cf& a, const Packet4cf& b)
|
||||||
{
|
{
|
||||||
return pdiv_complex(a, 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)
|
template<> EIGEN_STRONG_INLINE Packet4cf pcplxflip<Packet4cf>(const Packet4cf& x)
|
||||||
@@ -190,7 +228,6 @@ struct Packet2cd
|
|||||||
__m256d v;
|
__m256d v;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef EIGEN_VECTORIZE_AVX512
|
|
||||||
template<> struct packet_traits<std::complex<double> > : default_packet_traits
|
template<> struct packet_traits<std::complex<double> > : default_packet_traits
|
||||||
{
|
{
|
||||||
typedef Packet2cd type;
|
typedef Packet2cd type;
|
||||||
@@ -206,7 +243,6 @@ template<> struct packet_traits<std::complex<double> > : default_packet_traits
|
|||||||
HasMul = 1,
|
HasMul = 1,
|
||||||
HasDiv = 1,
|
HasDiv = 1,
|
||||||
HasNegate = 1,
|
HasNegate = 1,
|
||||||
HasSqrt = 1,
|
|
||||||
HasAbs = 0,
|
HasAbs = 0,
|
||||||
HasAbs2 = 0,
|
HasAbs2 = 0,
|
||||||
HasMin = 0,
|
HasMin = 0,
|
||||||
@@ -214,20 +250,8 @@ template<> struct packet_traits<std::complex<double> > : default_packet_traits
|
|||||||
HasSetLinear = 0
|
HasSetLinear = 0
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
template<> struct unpacket_traits<Packet2cd> {
|
template<> struct unpacket_traits<Packet2cd> { typedef std::complex<double> type; enum {size=2, alignment=Aligned32}; typedef Packet1cd half; };
|
||||||
typedef std::complex<double> type;
|
|
||||||
typedef Packet1cd half;
|
|
||||||
typedef Packet4d as_real;
|
|
||||||
enum {
|
|
||||||
size=2,
|
|
||||||
alignment=Aligned32,
|
|
||||||
vectorizable=true,
|
|
||||||
masked_load_available=false,
|
|
||||||
masked_store_available=false
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
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 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 psub<Packet2cd>(const Packet2cd& a, const Packet2cd& b) { return Packet2cd(_mm256_sub_pd(a.v,b.v)); }
|
||||||
@@ -248,17 +272,10 @@ template<> EIGEN_STRONG_INLINE Packet2cd pmul<Packet2cd>(const Packet2cd& a, con
|
|||||||
return Packet2cd(_mm256_addsub_pd(even, odd));
|
return Packet2cd(_mm256_addsub_pd(even, odd));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
|
||||||
EIGEN_STRONG_INLINE Packet2cd pcmp_eq(const Packet2cd& a, const Packet2cd& b) {
|
|
||||||
__m256d eq = _mm256_cmp_pd(a.v, b.v, _CMP_EQ_OQ);
|
|
||||||
return Packet2cd(pand(eq, _mm256_permute_pd(eq, 0x5)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet2cd ptrue<Packet2cd>(const Packet2cd& a) { return Packet2cd(ptrue(Packet4d(a.v))); }
|
|
||||||
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 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 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 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(b.v,a.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)
|
template<> EIGEN_STRONG_INLINE Packet2cd pload <Packet2cd>(const std::complex<double>* from)
|
||||||
{ EIGEN_DEBUG_ALIGNED_LOAD return Packet2cd(pload<Packet4d>((const double*)from)); }
|
{ EIGEN_DEBUG_ALIGNED_LOAD return Packet2cd(pload<Packet4d>((const double*)from)); }
|
||||||
@@ -310,17 +327,71 @@ template<> EIGEN_STRONG_INLINE std::complex<double> predux<Packet2cd>(const Pack
|
|||||||
Packet1cd(_mm256_extractf128_pd(a.v,1))));
|
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)
|
template<> EIGEN_STRONG_INLINE std::complex<double> predux_mul<Packet2cd>(const Packet2cd& a)
|
||||||
{
|
{
|
||||||
return predux(pmul(Packet1cd(_mm256_extractf128_pd(a.v,0)),
|
return predux(pmul(Packet1cd(_mm256_extractf128_pd(a.v,0)),
|
||||||
Packet1cd(_mm256_extractf128_pd(a.v,1))));
|
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));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cd,Packet4d)
|
EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cd,Packet4d)
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet2cd pdiv<Packet2cd>(const Packet2cd& a, const Packet2cd& b)
|
template<> EIGEN_STRONG_INLINE Packet2cd pdiv<Packet2cd>(const Packet2cd& a, const Packet2cd& b)
|
||||||
{
|
{
|
||||||
return pdiv_complex(a, 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)
|
template<> EIGEN_STRONG_INLINE Packet2cd pcplxflip<Packet2cd>(const Packet2cd& x)
|
||||||
@@ -353,12 +424,24 @@ ptranspose(PacketBlock<Packet2cd,2>& kernel) {
|
|||||||
kernel.packet[0].v = tmp;
|
kernel.packet[0].v = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet2cd psqrt<Packet2cd>(const Packet2cd& a) {
|
template<> EIGEN_STRONG_INLINE Packet4cf pinsertfirst(const Packet4cf& a, std::complex<float> b)
|
||||||
return psqrt_complex<Packet2cd>(a);
|
{
|
||||||
|
return Packet4cf(_mm256_blend_ps(a.v,pset1<Packet4cf>(b).v,1|2));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet4cf psqrt<Packet4cf>(const Packet4cf& a) {
|
template<> EIGEN_STRONG_INLINE Packet2cd pinsertfirst(const Packet2cd& a, std::complex<double> b)
|
||||||
return psqrt_complex<Packet4cf>(a);
|
{
|
||||||
|
return Packet2cd(_mm256_blend_pd(a.v,pset1<Packet2cd>(b).v,1|2));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> EIGEN_STRONG_INLINE Packet4cf pinsertlast(const Packet4cf& a, std::complex<float> b)
|
||||||
|
{
|
||||||
|
return Packet4cf(_mm256_blend_ps(a.v,pset1<Packet4cf>(b).v,(1<<7)|(1<<6)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> EIGEN_STRONG_INLINE Packet2cd pinsertlast(const Packet2cd& a, std::complex<double> b)
|
||||||
|
{
|
||||||
|
return Packet2cd(_mm256_blend_pd(a.v,pset1<Packet2cd>(b).v,(1<<3)|(1<<2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#ifndef EIGEN_MATH_FUNCTIONS_AVX_H
|
#ifndef EIGEN_MATH_FUNCTIONS_AVX_H
|
||||||
#define EIGEN_MATH_FUNCTIONS_AVX_H
|
#define EIGEN_MATH_FUNCTIONS_AVX_H
|
||||||
|
|
||||||
/* The sin and cos functions of this file are loosely derived from
|
/* The sin, cos, exp, and log functions of this file are loosely derived from
|
||||||
* Julien Pommier's sse math library: http://gruntthepeon.free.fr/ssemath/
|
* Julien Pommier's sse math library: http://gruntthepeon.free.fr/ssemath/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -18,50 +18,187 @@ namespace Eigen {
|
|||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
inline Packet8i pshiftleft(Packet8i v, int n)
|
||||||
|
{
|
||||||
|
#ifdef EIGEN_VECTORIZE_AVX2
|
||||||
|
return _mm256_slli_epi32(v, n);
|
||||||
|
#else
|
||||||
|
__m128i lo = _mm_slli_epi32(_mm256_extractf128_si256(v, 0), n);
|
||||||
|
__m128i hi = _mm_slli_epi32(_mm256_extractf128_si256(v, 1), n);
|
||||||
|
return _mm256_insertf128_si256(_mm256_castsi128_si256(lo), (hi), 1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Packet8f pshiftright(Packet8f v, int n)
|
||||||
|
{
|
||||||
|
#ifdef EIGEN_VECTORIZE_AVX2
|
||||||
|
return _mm256_cvtepi32_ps(_mm256_srli_epi32(_mm256_castps_si256(v), n));
|
||||||
|
#else
|
||||||
|
__m128i lo = _mm_srli_epi32(_mm256_extractf128_si256(_mm256_castps_si256(v), 0), n);
|
||||||
|
__m128i hi = _mm_srli_epi32(_mm256_extractf128_si256(_mm256_castps_si256(v), 1), n);
|
||||||
|
return _mm256_cvtepi32_ps(_mm256_insertf128_si256(_mm256_castsi128_si256(lo), (hi), 1));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sine function
|
||||||
|
// Computes sin(x) by wrapping x to the interval [-Pi/4,3*Pi/4] and
|
||||||
|
// evaluating interpolants in [-Pi/4,Pi/4] or [Pi/4,3*Pi/4]. The interpolants
|
||||||
|
// are (anti-)symmetric and thus have only odd/even coefficients
|
||||||
template <>
|
template <>
|
||||||
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet8f
|
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet8f
|
||||||
psin<Packet8f>(const Packet8f& _x) {
|
psin<Packet8f>(const Packet8f& _x) {
|
||||||
return psin_float(_x);
|
Packet8f x = _x;
|
||||||
}
|
|
||||||
|
// Some useful values.
|
||||||
template <>
|
_EIGEN_DECLARE_CONST_Packet8i(one, 1);
|
||||||
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet8f
|
_EIGEN_DECLARE_CONST_Packet8f(one, 1.0f);
|
||||||
pcos<Packet8f>(const Packet8f& _x) {
|
_EIGEN_DECLARE_CONST_Packet8f(two, 2.0f);
|
||||||
return pcos_float(_x);
|
_EIGEN_DECLARE_CONST_Packet8f(one_over_four, 0.25f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(one_over_pi, 3.183098861837907e-01f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(neg_pi_first, -3.140625000000000e+00f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(neg_pi_second, -9.670257568359375e-04f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(neg_pi_third, -6.278329571784980e-07f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(four_over_pi, 1.273239544735163e+00f);
|
||||||
|
|
||||||
|
// Map x from [-Pi/4,3*Pi/4] to z in [-1,3] and subtract the shifted period.
|
||||||
|
Packet8f z = pmul(x, p8f_one_over_pi);
|
||||||
|
Packet8f shift = _mm256_floor_ps(padd(z, p8f_one_over_four));
|
||||||
|
x = pmadd(shift, p8f_neg_pi_first, x);
|
||||||
|
x = pmadd(shift, p8f_neg_pi_second, x);
|
||||||
|
x = pmadd(shift, p8f_neg_pi_third, x);
|
||||||
|
z = pmul(x, p8f_four_over_pi);
|
||||||
|
|
||||||
|
// Make a mask for the entries that need flipping, i.e. wherever the shift
|
||||||
|
// is odd.
|
||||||
|
Packet8i shift_ints = _mm256_cvtps_epi32(shift);
|
||||||
|
Packet8i shift_isodd = _mm256_castps_si256(_mm256_and_ps(_mm256_castsi256_ps(shift_ints), _mm256_castsi256_ps(p8i_one)));
|
||||||
|
Packet8i sign_flip_mask = pshiftleft(shift_isodd, 31);
|
||||||
|
|
||||||
|
// Create a mask for which interpolant to use, i.e. if z > 1, then the mask
|
||||||
|
// is set to ones for that entry.
|
||||||
|
Packet8f ival_mask = _mm256_cmp_ps(z, p8f_one, _CMP_GT_OQ);
|
||||||
|
|
||||||
|
// Evaluate the polynomial for the interval [1,3] in z.
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(coeff_right_0, 9.999999724233232e-01f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(coeff_right_2, -3.084242535619928e-01f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(coeff_right_4, 1.584991525700324e-02f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(coeff_right_6, -3.188805084631342e-04f);
|
||||||
|
Packet8f z_minus_two = psub(z, p8f_two);
|
||||||
|
Packet8f z_minus_two2 = pmul(z_minus_two, z_minus_two);
|
||||||
|
Packet8f right = pmadd(p8f_coeff_right_6, z_minus_two2, p8f_coeff_right_4);
|
||||||
|
right = pmadd(right, z_minus_two2, p8f_coeff_right_2);
|
||||||
|
right = pmadd(right, z_minus_two2, p8f_coeff_right_0);
|
||||||
|
|
||||||
|
// Evaluate the polynomial for the interval [-1,1] in z.
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(coeff_left_1, 7.853981525427295e-01f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(coeff_left_3, -8.074536727092352e-02f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(coeff_left_5, 2.489871967827018e-03f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(coeff_left_7, -3.587725841214251e-05f);
|
||||||
|
Packet8f z2 = pmul(z, z);
|
||||||
|
Packet8f left = pmadd(p8f_coeff_left_7, z2, p8f_coeff_left_5);
|
||||||
|
left = pmadd(left, z2, p8f_coeff_left_3);
|
||||||
|
left = pmadd(left, z2, p8f_coeff_left_1);
|
||||||
|
left = pmul(left, z);
|
||||||
|
|
||||||
|
// Assemble the results, i.e. select the left and right polynomials.
|
||||||
|
left = _mm256_andnot_ps(ival_mask, left);
|
||||||
|
right = _mm256_and_ps(ival_mask, right);
|
||||||
|
Packet8f res = _mm256_or_ps(left, right);
|
||||||
|
|
||||||
|
// Flip the sign on the odd intervals and return the result.
|
||||||
|
res = _mm256_xor_ps(res, _mm256_castsi256_ps(sign_flip_mask));
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Natural logarithm
|
||||||
|
// Computes log(x) as log(2^e * m) = C*e + log(m), where the constant C =log(2)
|
||||||
|
// and m is in the range [sqrt(1/2),sqrt(2)). In this range, the logarithm can
|
||||||
|
// be easily approximated by a polynomial centered on m=1 for stability.
|
||||||
|
// TODO(gonnet): Further reduce the interval allowing for lower-degree
|
||||||
|
// polynomial interpolants -> ... -> profit!
|
||||||
template <>
|
template <>
|
||||||
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet8f
|
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet8f
|
||||||
plog<Packet8f>(const Packet8f& _x) {
|
plog<Packet8f>(const Packet8f& _x) {
|
||||||
return plog_float(_x);
|
Packet8f x = _x;
|
||||||
}
|
_EIGEN_DECLARE_CONST_Packet8f(1, 1.0f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(half, 0.5f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(126f, 126.0f);
|
||||||
|
|
||||||
template <>
|
_EIGEN_DECLARE_CONST_Packet8f_FROM_INT(inv_mant_mask, ~0x7f800000);
|
||||||
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet4d
|
|
||||||
plog<Packet4d>(const Packet4d& _x) {
|
|
||||||
return plog_double(_x);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
// The smallest non denormalized float number.
|
||||||
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet8f
|
_EIGEN_DECLARE_CONST_Packet8f_FROM_INT(min_norm_pos, 0x00800000);
|
||||||
plog2<Packet8f>(const Packet8f& _x) {
|
_EIGEN_DECLARE_CONST_Packet8f_FROM_INT(minus_inf, 0xff800000);
|
||||||
return plog2_float(_x);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
// Polynomial coefficients.
|
||||||
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet4d
|
_EIGEN_DECLARE_CONST_Packet8f(cephes_SQRTHF, 0.707106781186547524f);
|
||||||
plog2<Packet4d>(const Packet4d& _x) {
|
_EIGEN_DECLARE_CONST_Packet8f(cephes_log_p0, 7.0376836292E-2f);
|
||||||
return plog2_double(_x);
|
_EIGEN_DECLARE_CONST_Packet8f(cephes_log_p1, -1.1514610310E-1f);
|
||||||
}
|
_EIGEN_DECLARE_CONST_Packet8f(cephes_log_p2, 1.1676998740E-1f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(cephes_log_p3, -1.2420140846E-1f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(cephes_log_p4, +1.4249322787E-1f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(cephes_log_p5, -1.6668057665E-1f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(cephes_log_p6, +2.0000714765E-1f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(cephes_log_p7, -2.4999993993E-1f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(cephes_log_p8, +3.3333331174E-1f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(cephes_log_q1, -2.12194440e-4f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(cephes_log_q2, 0.693359375f);
|
||||||
|
|
||||||
template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
|
Packet8f invalid_mask = _mm256_cmp_ps(x, _mm256_setzero_ps(), _CMP_NGE_UQ); // not greater equal is true if x is NaN
|
||||||
Packet8f plog1p<Packet8f>(const Packet8f& _x) {
|
Packet8f iszero_mask = _mm256_cmp_ps(x, _mm256_setzero_ps(), _CMP_EQ_OQ);
|
||||||
return generic_plog1p(_x);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
|
// Truncate input values to the minimum positive normal.
|
||||||
Packet8f pexpm1<Packet8f>(const Packet8f& _x) {
|
x = pmax(x, p8f_min_norm_pos);
|
||||||
return generic_expm1(_x);
|
|
||||||
|
Packet8f emm0 = pshiftright(x,23);
|
||||||
|
Packet8f e = _mm256_sub_ps(emm0, p8f_126f);
|
||||||
|
|
||||||
|
// Set the exponents to -1, i.e. x are in the range [0.5,1).
|
||||||
|
x = _mm256_and_ps(x, p8f_inv_mant_mask);
|
||||||
|
x = _mm256_or_ps(x, p8f_half);
|
||||||
|
|
||||||
|
// part2: Shift the inputs from the range [0.5,1) to [sqrt(1/2),sqrt(2))
|
||||||
|
// and shift by -1. The values are then centered around 0, which improves
|
||||||
|
// the stability of the polynomial evaluation.
|
||||||
|
// if( x < SQRTHF ) {
|
||||||
|
// e -= 1;
|
||||||
|
// x = x + x - 1.0;
|
||||||
|
// } else { x = x - 1.0; }
|
||||||
|
Packet8f mask = _mm256_cmp_ps(x, p8f_cephes_SQRTHF, _CMP_LT_OQ);
|
||||||
|
Packet8f tmp = _mm256_and_ps(x, mask);
|
||||||
|
x = psub(x, p8f_1);
|
||||||
|
e = psub(e, _mm256_and_ps(p8f_1, mask));
|
||||||
|
x = padd(x, tmp);
|
||||||
|
|
||||||
|
Packet8f x2 = pmul(x, x);
|
||||||
|
Packet8f x3 = pmul(x2, x);
|
||||||
|
|
||||||
|
// Evaluate the polynomial approximant of degree 8 in three parts, probably
|
||||||
|
// to improve instruction-level parallelism.
|
||||||
|
Packet8f y, y1, y2;
|
||||||
|
y = pmadd(p8f_cephes_log_p0, x, p8f_cephes_log_p1);
|
||||||
|
y1 = pmadd(p8f_cephes_log_p3, x, p8f_cephes_log_p4);
|
||||||
|
y2 = pmadd(p8f_cephes_log_p6, x, p8f_cephes_log_p7);
|
||||||
|
y = pmadd(y, x, p8f_cephes_log_p2);
|
||||||
|
y1 = pmadd(y1, x, p8f_cephes_log_p5);
|
||||||
|
y2 = pmadd(y2, x, p8f_cephes_log_p8);
|
||||||
|
y = pmadd(y, x3, y1);
|
||||||
|
y = pmadd(y, x3, y2);
|
||||||
|
y = pmul(y, x3);
|
||||||
|
|
||||||
|
// Add the logarithm of the exponent back to the result of the interpolation.
|
||||||
|
y1 = pmul(e, p8f_cephes_log_q1);
|
||||||
|
tmp = pmul(x2, p8f_half);
|
||||||
|
y = padd(y, y1);
|
||||||
|
x = psub(x, tmp);
|
||||||
|
y2 = pmul(e, p8f_cephes_log_q2);
|
||||||
|
x = padd(x, y);
|
||||||
|
x = padd(x, y2);
|
||||||
|
|
||||||
|
// Filter out invalid inputs, i.e. negative arg will be NAN, 0 will be -INF.
|
||||||
|
return _mm256_or_ps(
|
||||||
|
_mm256_andnot_ps(iszero_mask, _mm256_or_ps(x, invalid_mask)),
|
||||||
|
_mm256_and_ps(iszero_mask, p8f_minus_inf));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exponential function. Works by writing "x = m*log(2) + r" where
|
// Exponential function. Works by writing "x = m*log(2) + r" where
|
||||||
@@ -70,21 +207,149 @@ Packet8f pexpm1<Packet8f>(const Packet8f& _x) {
|
|||||||
template <>
|
template <>
|
||||||
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet8f
|
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet8f
|
||||||
pexp<Packet8f>(const Packet8f& _x) {
|
pexp<Packet8f>(const Packet8f& _x) {
|
||||||
return pexp_float(_x);
|
_EIGEN_DECLARE_CONST_Packet8f(1, 1.0f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(half, 0.5f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(127, 127.0f);
|
||||||
|
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(exp_hi, 88.3762626647950f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(exp_lo, -88.3762626647949f);
|
||||||
|
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(cephes_LOG2EF, 1.44269504088896341f);
|
||||||
|
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(cephes_exp_p0, 1.9875691500E-4f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(cephes_exp_p1, 1.3981999507E-3f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(cephes_exp_p2, 8.3334519073E-3f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(cephes_exp_p3, 4.1665795894E-2f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(cephes_exp_p4, 1.6666665459E-1f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(cephes_exp_p5, 5.0000001201E-1f);
|
||||||
|
|
||||||
|
// Clamp x.
|
||||||
|
Packet8f x = pmax(pmin(_x, p8f_exp_hi), p8f_exp_lo);
|
||||||
|
|
||||||
|
// Express exp(x) as exp(m*ln(2) + r), start by extracting
|
||||||
|
// m = floor(x/ln(2) + 0.5).
|
||||||
|
Packet8f m = _mm256_floor_ps(pmadd(x, p8f_cephes_LOG2EF, p8f_half));
|
||||||
|
|
||||||
|
// Get r = x - m*ln(2). If no FMA instructions are available, m*ln(2) is
|
||||||
|
// subtracted out in two parts, m*C1+m*C2 = m*ln(2), to avoid accumulating
|
||||||
|
// truncation errors. Note that we don't use the "pmadd" function here to
|
||||||
|
// ensure that a precision-preserving FMA instruction is used.
|
||||||
|
#ifdef EIGEN_VECTORIZE_FMA
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(nln2, -0.6931471805599453f);
|
||||||
|
Packet8f r = _mm256_fmadd_ps(m, p8f_nln2, x);
|
||||||
|
#else
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(cephes_exp_C1, 0.693359375f);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f(cephes_exp_C2, -2.12194440e-4f);
|
||||||
|
Packet8f r = psub(x, pmul(m, p8f_cephes_exp_C1));
|
||||||
|
r = psub(r, pmul(m, p8f_cephes_exp_C2));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Packet8f r2 = pmul(r, r);
|
||||||
|
|
||||||
|
// TODO(gonnet): Split into odd/even polynomials and try to exploit
|
||||||
|
// instruction-level parallelism.
|
||||||
|
Packet8f y = p8f_cephes_exp_p0;
|
||||||
|
y = pmadd(y, r, p8f_cephes_exp_p1);
|
||||||
|
y = pmadd(y, r, p8f_cephes_exp_p2);
|
||||||
|
y = pmadd(y, r, p8f_cephes_exp_p3);
|
||||||
|
y = pmadd(y, r, p8f_cephes_exp_p4);
|
||||||
|
y = pmadd(y, r, p8f_cephes_exp_p5);
|
||||||
|
y = pmadd(y, r2, r);
|
||||||
|
y = padd(y, p8f_1);
|
||||||
|
|
||||||
|
// Build emm0 = 2^m.
|
||||||
|
Packet8i emm0 = _mm256_cvttps_epi32(padd(m, p8f_127));
|
||||||
|
emm0 = pshiftleft(emm0, 23);
|
||||||
|
|
||||||
|
// Return 2^m * exp(r).
|
||||||
|
return pmax(pmul(y, _mm256_castsi256_ps(emm0)), _x);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hyperbolic Tangent function.
|
// Hyperbolic Tangent function.
|
||||||
template <>
|
template <>
|
||||||
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet8f
|
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet8f
|
||||||
ptanh<Packet8f>(const Packet8f& _x) {
|
ptanh<Packet8f>(const Packet8f& x) {
|
||||||
return internal::generic_fast_tanh_float(_x);
|
return internal::generic_fast_tanh_float(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exponential function for doubles.
|
|
||||||
template <>
|
template <>
|
||||||
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet4d
|
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet4d
|
||||||
pexp<Packet4d>(const Packet4d& _x) {
|
pexp<Packet4d>(const Packet4d& _x) {
|
||||||
return pexp_double(_x);
|
Packet4d x = _x;
|
||||||
|
|
||||||
|
_EIGEN_DECLARE_CONST_Packet4d(1, 1.0);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet4d(2, 2.0);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet4d(half, 0.5);
|
||||||
|
|
||||||
|
_EIGEN_DECLARE_CONST_Packet4d(exp_hi, 709.437);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet4d(exp_lo, -709.436139303);
|
||||||
|
|
||||||
|
_EIGEN_DECLARE_CONST_Packet4d(cephes_LOG2EF, 1.4426950408889634073599);
|
||||||
|
|
||||||
|
_EIGEN_DECLARE_CONST_Packet4d(cephes_exp_p0, 1.26177193074810590878e-4);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet4d(cephes_exp_p1, 3.02994407707441961300e-2);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet4d(cephes_exp_p2, 9.99999999999999999910e-1);
|
||||||
|
|
||||||
|
_EIGEN_DECLARE_CONST_Packet4d(cephes_exp_q0, 3.00198505138664455042e-6);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet4d(cephes_exp_q1, 2.52448340349684104192e-3);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet4d(cephes_exp_q2, 2.27265548208155028766e-1);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet4d(cephes_exp_q3, 2.00000000000000000009e0);
|
||||||
|
|
||||||
|
_EIGEN_DECLARE_CONST_Packet4d(cephes_exp_C1, 0.693145751953125);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet4d(cephes_exp_C2, 1.42860682030941723212e-6);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet4i(1023, 1023);
|
||||||
|
|
||||||
|
Packet4d tmp, fx;
|
||||||
|
|
||||||
|
// clamp x
|
||||||
|
x = pmax(pmin(x, p4d_exp_hi), p4d_exp_lo);
|
||||||
|
// Express exp(x) as exp(g + n*log(2)).
|
||||||
|
fx = pmadd(p4d_cephes_LOG2EF, x, p4d_half);
|
||||||
|
|
||||||
|
// Get the integer modulus of log(2), i.e. the "n" described above.
|
||||||
|
fx = _mm256_floor_pd(fx);
|
||||||
|
|
||||||
|
// Get the remainder modulo log(2), i.e. the "g" described above. Subtract
|
||||||
|
// n*log(2) out in two steps, i.e. n*C1 + n*C2, C1+C2=log2 to get the last
|
||||||
|
// digits right.
|
||||||
|
tmp = pmul(fx, p4d_cephes_exp_C1);
|
||||||
|
Packet4d z = pmul(fx, p4d_cephes_exp_C2);
|
||||||
|
x = psub(x, tmp);
|
||||||
|
x = psub(x, z);
|
||||||
|
|
||||||
|
Packet4d x2 = pmul(x, x);
|
||||||
|
|
||||||
|
// Evaluate the numerator polynomial of the rational interpolant.
|
||||||
|
Packet4d px = p4d_cephes_exp_p0;
|
||||||
|
px = pmadd(px, x2, p4d_cephes_exp_p1);
|
||||||
|
px = pmadd(px, x2, p4d_cephes_exp_p2);
|
||||||
|
px = pmul(px, x);
|
||||||
|
|
||||||
|
// Evaluate the denominator polynomial of the rational interpolant.
|
||||||
|
Packet4d qx = p4d_cephes_exp_q0;
|
||||||
|
qx = pmadd(qx, x2, p4d_cephes_exp_q1);
|
||||||
|
qx = pmadd(qx, x2, p4d_cephes_exp_q2);
|
||||||
|
qx = pmadd(qx, x2, p4d_cephes_exp_q3);
|
||||||
|
|
||||||
|
// I don't really get this bit, copied from the SSE2 routines, so...
|
||||||
|
// TODO(gonnet): Figure out what is going on here, perhaps find a better
|
||||||
|
// rational interpolant?
|
||||||
|
x = _mm256_div_pd(px, psub(qx, px));
|
||||||
|
x = pmadd(p4d_2, x, p4d_1);
|
||||||
|
|
||||||
|
// Build e=2^n by constructing the exponents in a 128-bit vector and
|
||||||
|
// shifting them to where they belong in double-precision values.
|
||||||
|
__m128i emm0 = _mm256_cvtpd_epi32(fx);
|
||||||
|
emm0 = _mm_add_epi32(emm0, p4i_1023);
|
||||||
|
emm0 = _mm_shuffle_epi32(emm0, _MM_SHUFFLE(3, 1, 2, 0));
|
||||||
|
__m128i lo = _mm_slli_epi64(emm0, 52);
|
||||||
|
__m128i hi = _mm_slli_epi64(_mm_srli_epi64(emm0, 32), 52);
|
||||||
|
__m256i e = _mm256_insertf128_si256(_mm256_setzero_si256(), lo, 0);
|
||||||
|
e = _mm256_insertf128_si256(e, hi, 1);
|
||||||
|
|
||||||
|
// Construct the result 2^n * exp(g) = e * x. The max is used to catch
|
||||||
|
// non-finite values in the input.
|
||||||
|
return pmax(pmul(x, _mm256_castsi256_pd(e)), _x);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Functions for sqrt.
|
// Functions for sqrt.
|
||||||
@@ -97,39 +362,37 @@ pexp<Packet4d>(const Packet4d& _x) {
|
|||||||
// For detail see here: http://www.beyond3d.com/content/articles/8/
|
// For detail see here: http://www.beyond3d.com/content/articles/8/
|
||||||
#if EIGEN_FAST_MATH
|
#if EIGEN_FAST_MATH
|
||||||
template <>
|
template <>
|
||||||
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
|
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet8f
|
||||||
Packet8f psqrt<Packet8f>(const Packet8f& _x) {
|
psqrt<Packet8f>(const Packet8f& _x) {
|
||||||
Packet8f minus_half_x = pmul(_x, pset1<Packet8f>(-0.5f));
|
Packet8f half = pmul(_x, pset1<Packet8f>(.5f));
|
||||||
Packet8f denormal_mask = pandnot(
|
Packet8f denormal_mask = _mm256_and_ps(
|
||||||
pcmp_lt(_x, pset1<Packet8f>((std::numeric_limits<float>::min)())),
|
_mm256_cmp_ps(_x, pset1<Packet8f>((std::numeric_limits<float>::min)()),
|
||||||
pcmp_lt(_x, pzero(_x)));
|
_CMP_LT_OQ),
|
||||||
|
_mm256_cmp_ps(_x, _mm256_setzero_ps(), _CMP_GE_OQ));
|
||||||
|
|
||||||
// Compute approximate reciprocal sqrt.
|
// Compute approximate reciprocal sqrt.
|
||||||
Packet8f x = _mm256_rsqrt_ps(_x);
|
Packet8f x = _mm256_rsqrt_ps(_x);
|
||||||
// Do a single step of Newton's iteration.
|
// Do a single step of Newton's iteration.
|
||||||
x = pmul(x, pmadd(minus_half_x, pmul(x,x), pset1<Packet8f>(1.5f)));
|
x = pmul(x, psub(pset1<Packet8f>(1.5f), pmul(half, pmul(x,x))));
|
||||||
// Flush results for denormals to zero.
|
// Flush results for denormals to zero.
|
||||||
return pandnot(pmul(_x,x), denormal_mask);
|
return _mm256_andnot_ps(denormal_mask, pmul(_x,x));
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
template <> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
|
template <> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
|
||||||
Packet8f psqrt<Packet8f>(const Packet8f& _x) {
|
Packet8f psqrt<Packet8f>(const Packet8f& x) {
|
||||||
return _mm256_sqrt_ps(_x);
|
return _mm256_sqrt_ps(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
|
template <> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
|
||||||
Packet4d psqrt<Packet4d>(const Packet4d& _x) {
|
Packet4d psqrt<Packet4d>(const Packet4d& x) {
|
||||||
return _mm256_sqrt_pd(_x);
|
return _mm256_sqrt_pd(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if EIGEN_FAST_MATH
|
#if EIGEN_FAST_MATH
|
||||||
|
|
||||||
template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
|
template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
|
||||||
Packet8f prsqrt<Packet8f>(const Packet8f& _x) {
|
Packet8f prsqrt<Packet8f>(const Packet8f& _x) {
|
||||||
_EIGEN_DECLARE_CONST_Packet8f_FROM_INT(inf, 0x7f800000);
|
_EIGEN_DECLARE_CONST_Packet8f_FROM_INT(inf, 0x7f800000);
|
||||||
|
_EIGEN_DECLARE_CONST_Packet8f_FROM_INT(nan, 0x7fc00000);
|
||||||
_EIGEN_DECLARE_CONST_Packet8f(one_point_five, 1.5f);
|
_EIGEN_DECLARE_CONST_Packet8f(one_point_five, 1.5f);
|
||||||
_EIGEN_DECLARE_CONST_Packet8f(minus_half, -0.5f);
|
_EIGEN_DECLARE_CONST_Packet8f(minus_half, -0.5f);
|
||||||
_EIGEN_DECLARE_CONST_Packet8f_FROM_INT(flt_min, 0x00800000);
|
_EIGEN_DECLARE_CONST_Packet8f_FROM_INT(flt_min, 0x00800000);
|
||||||
@@ -138,88 +401,36 @@ Packet8f prsqrt<Packet8f>(const Packet8f& _x) {
|
|||||||
|
|
||||||
// select only the inverse sqrt of positive normal inputs (denormals are
|
// select only the inverse sqrt of positive normal inputs (denormals are
|
||||||
// flushed to zero and cause infs as well).
|
// flushed to zero and cause infs as well).
|
||||||
Packet8f lt_min_mask = _mm256_cmp_ps(_x, p8f_flt_min, _CMP_LT_OQ);
|
Packet8f le_zero_mask = _mm256_cmp_ps(_x, p8f_flt_min, _CMP_LT_OQ);
|
||||||
Packet8f inf_mask = _mm256_cmp_ps(_x, p8f_inf, _CMP_EQ_OQ);
|
Packet8f x = _mm256_andnot_ps(le_zero_mask, _mm256_rsqrt_ps(_x));
|
||||||
Packet8f not_normal_finite_mask = _mm256_or_ps(lt_min_mask, inf_mask);
|
|
||||||
|
|
||||||
// Compute an approximate result using the rsqrt intrinsic.
|
// Fill in NaNs and Infs for the negative/zero entries.
|
||||||
Packet8f y_approx = _mm256_rsqrt_ps(_x);
|
Packet8f neg_mask = _mm256_cmp_ps(_x, _mm256_setzero_ps(), _CMP_LT_OQ);
|
||||||
|
Packet8f zero_mask = _mm256_andnot_ps(neg_mask, le_zero_mask);
|
||||||
|
Packet8f infs_and_nans = _mm256_or_ps(_mm256_and_ps(neg_mask, p8f_nan),
|
||||||
|
_mm256_and_ps(zero_mask, p8f_inf));
|
||||||
|
|
||||||
// Do a single step of Newton-Raphson iteration to improve the approximation.
|
// Do a single step of Newton's iteration.
|
||||||
// This uses the formula y_{n+1} = y_n * (1.5 - y_n * (0.5 * x) * y_n).
|
x = pmul(x, pmadd(neg_half, pmul(x, x), p8f_one_point_five));
|
||||||
// It is essential to evaluate the inner term like this because forming
|
|
||||||
// y_n^2 may over- or underflow.
|
|
||||||
Packet8f y_newton = pmul(y_approx, pmadd(y_approx, pmul(neg_half, y_approx), p8f_one_point_five));
|
|
||||||
|
|
||||||
// Select the result of the Newton-Raphson step for positive normal arguments.
|
// Insert NaNs and Infs in all the right places.
|
||||||
// For other arguments, choose the output of the intrinsic. This will
|
return _mm256_or_ps(x, infs_and_nans);
|
||||||
// return rsqrt(+inf) = 0, rsqrt(x) = NaN if x < 0, and rsqrt(x) = +inf if
|
|
||||||
// x is zero or a positive denormalized float (equivalent to flushing positive
|
|
||||||
// denormalized inputs to zero).
|
|
||||||
return pselect<Packet8f>(not_normal_finite_mask, y_approx, y_newton);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
template <> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
|
template <> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
|
||||||
Packet8f prsqrt<Packet8f>(const Packet8f& _x) {
|
Packet8f prsqrt<Packet8f>(const Packet8f& x) {
|
||||||
_EIGEN_DECLARE_CONST_Packet8f(one, 1.0f);
|
_EIGEN_DECLARE_CONST_Packet8f(one, 1.0f);
|
||||||
return _mm256_div_ps(p8f_one, _mm256_sqrt_ps(_x));
|
return _mm256_div_ps(p8f_one, _mm256_sqrt_ps(x));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
|
template <> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
|
||||||
Packet4d prsqrt<Packet4d>(const Packet4d& _x) {
|
Packet4d prsqrt<Packet4d>(const Packet4d& x) {
|
||||||
_EIGEN_DECLARE_CONST_Packet4d(one, 1.0);
|
_EIGEN_DECLARE_CONST_Packet4d(one, 1.0);
|
||||||
return _mm256_div_pd(p4d_one, _mm256_sqrt_pd(_x));
|
return _mm256_div_pd(p4d_one, _mm256_sqrt_pd(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
F16_PACKET_FUNCTION(Packet8f, Packet8h, psin)
|
|
||||||
F16_PACKET_FUNCTION(Packet8f, Packet8h, pcos)
|
|
||||||
F16_PACKET_FUNCTION(Packet8f, Packet8h, plog)
|
|
||||||
F16_PACKET_FUNCTION(Packet8f, Packet8h, plog2)
|
|
||||||
F16_PACKET_FUNCTION(Packet8f, Packet8h, plog1p)
|
|
||||||
F16_PACKET_FUNCTION(Packet8f, Packet8h, pexpm1)
|
|
||||||
F16_PACKET_FUNCTION(Packet8f, Packet8h, pexp)
|
|
||||||
F16_PACKET_FUNCTION(Packet8f, Packet8h, ptanh)
|
|
||||||
F16_PACKET_FUNCTION(Packet8f, Packet8h, psqrt)
|
|
||||||
F16_PACKET_FUNCTION(Packet8f, Packet8h, prsqrt)
|
|
||||||
|
|
||||||
template <>
|
|
||||||
EIGEN_STRONG_INLINE Packet8h pfrexp(const Packet8h& a, Packet8h& exponent) {
|
|
||||||
Packet8f fexponent;
|
|
||||||
const Packet8h out = float2half(pfrexp<Packet8f>(half2float(a), fexponent));
|
|
||||||
exponent = float2half(fexponent);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
EIGEN_STRONG_INLINE Packet8h pldexp(const Packet8h& a, const Packet8h& exponent) {
|
|
||||||
return float2half(pldexp<Packet8f>(half2float(a), half2float(exponent)));
|
|
||||||
}
|
|
||||||
|
|
||||||
BF16_PACKET_FUNCTION(Packet8f, Packet8bf, psin)
|
|
||||||
BF16_PACKET_FUNCTION(Packet8f, Packet8bf, pcos)
|
|
||||||
BF16_PACKET_FUNCTION(Packet8f, Packet8bf, plog)
|
|
||||||
BF16_PACKET_FUNCTION(Packet8f, Packet8bf, plog2)
|
|
||||||
BF16_PACKET_FUNCTION(Packet8f, Packet8bf, plog1p)
|
|
||||||
BF16_PACKET_FUNCTION(Packet8f, Packet8bf, pexpm1)
|
|
||||||
BF16_PACKET_FUNCTION(Packet8f, Packet8bf, pexp)
|
|
||||||
BF16_PACKET_FUNCTION(Packet8f, Packet8bf, ptanh)
|
|
||||||
BF16_PACKET_FUNCTION(Packet8f, Packet8bf, psqrt)
|
|
||||||
BF16_PACKET_FUNCTION(Packet8f, Packet8bf, prsqrt)
|
|
||||||
|
|
||||||
template <>
|
|
||||||
EIGEN_STRONG_INLINE Packet8bf pfrexp(const Packet8bf& a, Packet8bf& exponent) {
|
|
||||||
Packet8f fexponent;
|
|
||||||
const Packet8bf out = F32ToBf16(pfrexp<Packet8f>(Bf16ToF32(a), fexponent));
|
|
||||||
exponent = F32ToBf16(fexponent);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
EIGEN_STRONG_INLINE Packet8bf pldexp(const Packet8bf& a, const Packet8bf& exponent) {
|
|
||||||
return F32ToBf16(pldexp<Packet8f>(Bf16ToF32(a), Bf16ToF32(exponent)));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -35,79 +35,15 @@ struct type_casting_traits<int, float> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifndef EIGEN_VECTORIZE_AVX512
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct type_casting_traits<Eigen::half, float> {
|
|
||||||
enum {
|
|
||||||
VectorizedCast = 1,
|
|
||||||
SrcCoeffRatio = 1,
|
|
||||||
TgtCoeffRatio = 1
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct type_casting_traits<float, Eigen::half> {
|
|
||||||
enum {
|
|
||||||
VectorizedCast = 1,
|
|
||||||
SrcCoeffRatio = 1,
|
|
||||||
TgtCoeffRatio = 1
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct type_casting_traits<bfloat16, float> {
|
|
||||||
enum {
|
|
||||||
VectorizedCast = 1,
|
|
||||||
SrcCoeffRatio = 1,
|
|
||||||
TgtCoeffRatio = 1
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct type_casting_traits<float, bfloat16> {
|
|
||||||
enum {
|
|
||||||
VectorizedCast = 1,
|
|
||||||
SrcCoeffRatio = 1,
|
|
||||||
TgtCoeffRatio = 1
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // EIGEN_VECTORIZE_AVX512
|
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet8i pcast<Packet8f, Packet8i>(const Packet8f& a) {
|
template<> EIGEN_STRONG_INLINE Packet8i pcast<Packet8f, Packet8i>(const Packet8f& a) {
|
||||||
return _mm256_cvttps_epi32(a);
|
return _mm256_cvtps_epi32(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet8f pcast<Packet8i, Packet8f>(const Packet8i& a) {
|
template<> EIGEN_STRONG_INLINE Packet8f pcast<Packet8i, Packet8f>(const Packet8i& a) {
|
||||||
return _mm256_cvtepi32_ps(a);
|
return _mm256_cvtepi32_ps(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet8i preinterpret<Packet8i,Packet8f>(const Packet8f& a) {
|
|
||||||
return _mm256_castps_si256(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet8f preinterpret<Packet8f,Packet8i>(const Packet8i& a) {
|
|
||||||
return _mm256_castsi256_ps(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet8f pcast<Packet8h, Packet8f>(const Packet8h& a) {
|
|
||||||
return half2float(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet8f pcast<Packet8bf, Packet8f>(const Packet8bf& a) {
|
|
||||||
return Bf16ToF32(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet8h pcast<Packet8f, Packet8h>(const Packet8f& a) {
|
|
||||||
return float2half(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet8bf pcast<Packet8f, Packet8bf>(const Packet8f& a) {
|
|
||||||
return F32ToBf16(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user