mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Compare commits
160 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bdcab83e28 | ||
|
|
5c9addf4a2 | ||
|
|
05bd58e9b4 | ||
|
|
69f583a866 | ||
|
|
49016cbe4b | ||
|
|
43f054dbb4 | ||
|
|
2a965155af | ||
|
|
5ce83aeb6b | ||
|
|
41070aad7b | ||
|
|
27f6fd3a50 | ||
|
|
45ae9a069c | ||
|
|
bdd80ebe1c | ||
|
|
06773276cd | ||
|
|
c8271df0ec | ||
|
|
9e84d135db | ||
|
|
8d2f7ae94b | ||
|
|
a1a0cccd4e | ||
|
|
45e1bb5ea5 | ||
|
|
d0c374f1ed | ||
|
|
f231560ec2 | ||
|
|
cea814b90d | ||
|
|
15b1558483 | ||
|
|
bfe9b35152 | ||
|
|
6d4f7f76ce | ||
|
|
b4c4490587 | ||
|
|
6af80a23a5 | ||
|
|
f1f70ceb84 | ||
|
|
ea1ac035ce | ||
|
|
360a79d6f8 | ||
|
|
057254381d | ||
|
|
cafd34fa91 | ||
|
|
deeffdb245 | ||
|
|
10295de37b | ||
|
|
c31b70fcfd | ||
|
|
b55585a93d | ||
|
|
ae32b89b12 | ||
|
|
0007cc3dd7 | ||
|
|
2bde6013c9 | ||
|
|
7b9d54ba58 | ||
|
|
457e4b2493 | ||
|
|
f54cc2284e | ||
|
|
503cf43556 | ||
|
|
b9e2b4f6f5 | ||
|
|
2c2b7f4173 | ||
|
|
fd52daae87 | ||
|
|
61ad84fd4d | ||
|
|
0fa2b394ce | ||
|
|
bc0fc5d21e | ||
|
|
45bcad41b4 | ||
|
|
28bbc4bf47 | ||
|
|
05f45cfecd | ||
|
|
01e13a273e | ||
|
|
5437ab95fd | ||
|
|
a45de92246 | ||
|
|
1d68e47a23 | ||
|
|
41b0fd733f | ||
|
|
228920fad7 | ||
|
|
dcb36e3d49 | ||
|
|
11a31f2eba | ||
|
|
874d4e9f30 | ||
|
|
99d8e5de2b | ||
|
|
a52ab9c089 | ||
|
|
9ed342a30e | ||
|
|
0ef41ec958 | ||
|
|
7438c2d3ce | ||
|
|
7764885d04 | ||
|
|
6021b5c467 | ||
|
|
1ab1f7b125 | ||
|
|
411b4a1b1d | ||
|
|
8f7fb19907 | ||
|
|
074755a27c | ||
|
|
37725a72db | ||
|
|
0d1f7ed252 | ||
|
|
bef5ada15a | ||
|
|
bababb5bd6 | ||
|
|
9d0fcacc72 | ||
|
|
1f974f33d8 | ||
|
|
f698fbed62 | ||
|
|
db08fb676b | ||
|
|
3a0d0df82d | ||
|
|
af34da6438 | ||
|
|
9c92d70f1d | ||
|
|
b6fc4cfe2a | ||
|
|
467b7b9263 | ||
|
|
48fdb50ae3 | ||
|
|
a65053d80b | ||
|
|
adcb220db3 | ||
|
|
b21f9c3573 | ||
|
|
fe228fc50b | ||
|
|
4ab20b4cae | ||
|
|
5d5cf478ab | ||
|
|
55149df4e8 | ||
|
|
b2d10249b4 | ||
|
|
bdf0b0c47e | ||
|
|
ea7923c6f9 | ||
|
|
49b6e9143e | ||
|
|
f096553344 | ||
|
|
433b353013 | ||
|
|
3cb088c39f | ||
|
|
a99ea69b32 | ||
|
|
d03bbcbcbc | ||
|
|
fae2aa3fd9 | ||
|
|
13a17d968f | ||
|
|
135ba535a4 | ||
|
|
bbbf0559fe | ||
|
|
c91fed1eec | ||
|
|
f59b08f3bd | ||
|
|
9155002901 | ||
|
|
46f4bd9ed4 | ||
|
|
ebad34db21 | ||
|
|
c0f867ed10 | ||
|
|
d225bbe534 | ||
|
|
a6f8da7c48 | ||
|
|
33efb8ed62 | ||
|
|
63e5cf525f | ||
|
|
3cd1641dac | ||
|
|
4fe4ab8fc0 | ||
|
|
d7d76bf4ca | ||
|
|
cf76a50a34 | ||
|
|
ee46ae9ba7 | ||
|
|
b3c3627c72 | ||
|
|
e3a521be6b | ||
|
|
4c7d57490c | ||
|
|
fe21e084b4 | ||
|
|
282fd7a2da | ||
|
|
7d28c618a0 | ||
|
|
f07fca2c80 | ||
|
|
99ab2411e5 | ||
|
|
ffefe1bd2e | ||
|
|
55574053d0 | ||
|
|
ffee1d1c87 | ||
|
|
adf5992767 | ||
|
|
19e7c672bb | ||
|
|
99a6178e6a | ||
|
|
c3342b0bb4 | ||
|
|
84c8b6d5c5 | ||
|
|
18a8034348 | ||
|
|
697e1656ce | ||
|
|
c2a23c3e24 | ||
|
|
6d0e3154d7 | ||
|
|
7b122ed158 | ||
|
|
d9232a96aa | ||
|
|
4ecf67f5e4 | ||
|
|
860d66c0f1 | ||
|
|
ba3aafa85f | ||
|
|
b478521ecd | ||
|
|
e8fa6dde01 | ||
|
|
134b83c310 | ||
|
|
b0e810fb3f | ||
|
|
dee686f762 | ||
|
|
90cacfa610 | ||
|
|
de21678aab | ||
|
|
a700d3c506 | ||
|
|
fc4684fe97 | ||
|
|
c088ee78c8 | ||
|
|
e53539435d | ||
|
|
1e8b834ceb | ||
|
|
3c510db6bf | ||
|
|
72ffb63165 | ||
|
|
67e24b85a4 |
@@ -1,19 +0,0 @@
|
|||||||
---
|
|
||||||
BasedOnStyle: Google
|
|
||||||
ColumnLimit: 120
|
|
||||||
---
|
|
||||||
Language: Cpp
|
|
||||||
BasedOnStyle: Google
|
|
||||||
ColumnLimit: 120
|
|
||||||
StatementMacros:
|
|
||||||
- EIGEN_STATIC_ASSERT
|
|
||||||
- EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
|
|
||||||
- EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
|
|
||||||
SortIncludes: false
|
|
||||||
AttributeMacros:
|
|
||||||
- EIGEN_STRONG_INLINE
|
|
||||||
- EIGEN_ALWAYS_INLINE
|
|
||||||
- EIGEN_DEVICE_FUNC
|
|
||||||
- EIGEN_DONT_INLINE
|
|
||||||
- EIGEN_DEPRECATED
|
|
||||||
- EIGEN_UNUSED
|
|
||||||
37
.clang-tidy
37
.clang-tidy
@@ -1,37 +0,0 @@
|
|||||||
---
|
|
||||||
# Conservative clang-tidy configuration for Eigen.
|
|
||||||
#
|
|
||||||
# Focuses on bug-finding checks with low false-positive rates.
|
|
||||||
# Intentionally omits style-enforcement checks (modernize-*, google-*,
|
|
||||||
# cppcoreguidelines-*) since Eigen has its own conventions and is a
|
|
||||||
# heavily-templated math library where many "modern C++" idioms don't apply.
|
|
||||||
|
|
||||||
Checks: >
|
|
||||||
-*,
|
|
||||||
bugprone-*,
|
|
||||||
-bugprone-narrowing-conversions,
|
|
||||||
-bugprone-easily-swappable-parameters,
|
|
||||||
-bugprone-implicit-widening-of-multiplication-result,
|
|
||||||
-bugprone-exception-escape,
|
|
||||||
misc-redundant-expression,
|
|
||||||
misc-unused-using-decls,
|
|
||||||
misc-misleading-identifier,
|
|
||||||
performance-for-range-copy,
|
|
||||||
performance-implicit-conversion-in-loop,
|
|
||||||
performance-unnecessary-copy-initialization,
|
|
||||||
performance-unnecessary-value-param,
|
|
||||||
readability-container-size-empty,
|
|
||||||
readability-duplicate-include,
|
|
||||||
readability-misleading-indentation,
|
|
||||||
readability-redundant-control-flow,
|
|
||||||
readability-redundant-smartptr-get,
|
|
||||||
|
|
||||||
WarningsAsErrors: ''
|
|
||||||
|
|
||||||
HeaderFilterRegex: 'Eigen/.*|test/.*|blas/.*|lapack/.*|unsupported/Eigen/.*'
|
|
||||||
|
|
||||||
# Eigen uses its own assert macros.
|
|
||||||
CheckOptions:
|
|
||||||
- key: bugprone-assert-side-effect.AssertMacros
|
|
||||||
value: 'eigen_assert,eigen_internal_assert,EIGEN_STATIC_ASSERT,VERIFY,VERIFY_IS_APPROX,VERIFY_IS_EQUAL,VERIFY_IS_MUCH_SMALLER_THAN,VERIFY_IS_NOT_APPROX,VERIFY_IS_NOT_EQUAL,VERIFY_IS_UNITARY,VERIFY_RAISES_ASSERT'
|
|
||||||
...
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
# First major clang-format MR (https://gitlab.com/libeigen/eigen/-/merge_requests/1429).
|
|
||||||
f38e16c193d489c278c189bc06b448a94adb45fb
|
|
||||||
# Formatting of tests, examples, benchmarks, et cetera (https://gitlab.com/libeigen/eigen/-/merge_requests/1432).
|
|
||||||
46e9cdb7fea25d7f7aef4332b9c3ead3857e213d
|
|
||||||
3
.gitattributes
vendored
3
.gitattributes
vendored
@@ -1,3 +0,0 @@
|
|||||||
*.sh eol=lf
|
|
||||||
debug/msvc/*.dat eol=crlf
|
|
||||||
debug/msvc/*.natvis eol=crlf
|
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -39,4 +39,3 @@ Makefile
|
|||||||
!scripts/buildtests.in
|
!scripts/buildtests.in
|
||||||
!Eigen/Core
|
!Eigen/Core
|
||||||
!Eigen/src/Core
|
!Eigen/src/Core
|
||||||
CLAUDE.md
|
|
||||||
|
|||||||
@@ -7,27 +7,8 @@
|
|||||||
# 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
|
||||||
# with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
default:
|
|
||||||
interruptible: true
|
|
||||||
|
|
||||||
# For MR pipelines, auto-cancel running jobs when new commits are pushed.
|
|
||||||
# For scheduled (nightly) pipelines, never auto-cancel so all jobs run to
|
|
||||||
# completion and all failures are visible for debugging.
|
|
||||||
workflow:
|
|
||||||
auto_cancel:
|
|
||||||
on_new_commit: interruptible
|
|
||||||
on_job_failure: none
|
|
||||||
rules:
|
|
||||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
|
||||||
auto_cancel:
|
|
||||||
on_new_commit: none
|
|
||||||
- when: always
|
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- checkformat
|
|
||||||
- build
|
- build
|
||||||
- test
|
|
||||||
- benchmark
|
|
||||||
- deploy
|
- deploy
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
@@ -42,11 +23,6 @@ variables:
|
|||||||
EIGEN_CI_CTEST_ARGS: ""
|
EIGEN_CI_CTEST_ARGS: ""
|
||||||
|
|
||||||
include:
|
include:
|
||||||
- "/ci/checkformat.gitlab-ci.yml"
|
|
||||||
- "/ci/common.gitlab-ci.yml"
|
- "/ci/common.gitlab-ci.yml"
|
||||||
- "/ci/build.linux.gitlab-ci.yml"
|
- "/ci/build.linux.gitlab-ci.yml"
|
||||||
- "/ci/build.windows.gitlab-ci.yml"
|
|
||||||
- "/ci/test.linux.gitlab-ci.yml"
|
|
||||||
- "/ci/test.windows.gitlab-ci.yml"
|
|
||||||
- "/ci/benchmark.gitlab-ci.yml"
|
|
||||||
- "/ci/deploy.gitlab-ci.yml"
|
- "/ci/deploy.gitlab-ci.yml"
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
<!--
|
|
||||||
Thank you for submitting an issue!
|
|
||||||
|
|
||||||
Before opening a new issue, please search for keywords in the existing [list of issues](https://gitlab.com/libeigen/eigen/-/issues?state=opened) to verify it isn't a duplicate.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Summary
|
|
||||||
<!-- Summarize the bug encountered concisely. -->
|
|
||||||
|
|
||||||
### Environment
|
|
||||||
<!-- Please provide your development environment. -->
|
|
||||||
- **Operating System** : Windows/Linux
|
|
||||||
- **Architecture** : x64/Arm64/PowerPC ...
|
|
||||||
- **Eigen Version** : 5.0.0
|
|
||||||
- **Compiler Version** : gcc-12.0
|
|
||||||
- **Compile Flags** : -O3 -march=native
|
|
||||||
- **Vector Extension** : SSE/AVX/NEON ...
|
|
||||||
|
|
||||||
### Minimal Example
|
|
||||||
<!--
|
|
||||||
Please create a minimal reproducing example here that exhibits the problematic behavior.
|
|
||||||
The example should be complete, in that it can fully build and run. See the [the guidelines on stackoverflow](https://stackoverflow.com/help/minimal-reproducible-example) for how to create a good minimal example.
|
|
||||||
|
|
||||||
You can also link to [godbolt](https://godbolt.org). Note that you need to click
|
|
||||||
the "Share" button in the top right-hand corner of the godbolt page to get the share link
|
|
||||||
instead of the URL in your browser address bar.
|
|
||||||
-->
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
// Insert your code here.
|
|
||||||
```
|
|
||||||
|
|
||||||
### Steps to reproduce the issue
|
|
||||||
<!-- Describe the necessary steps to reproduce the issue. -->
|
|
||||||
|
|
||||||
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 build logs or program output within blocks marked by " ``` " -->
|
|
||||||
|
|
||||||
### [Optional] 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).
|
|
||||||
-->
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
<!--
|
|
||||||
Thank you for submitting a Feature Request!
|
|
||||||
|
|
||||||
If you want to run ideas by the maintainers and the Eigen community first,
|
|
||||||
you can chat about them on the [Eigen Discord server](https://discord.gg/2SkEJGqZjR).
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Describe the feature you would like to be implemented.
|
|
||||||
|
|
||||||
### Why Would such a feature be useful for other users?
|
|
||||||
|
|
||||||
### Any hints on how to implement the requested feature?
|
|
||||||
|
|
||||||
### Additional resources
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
<!--
|
|
||||||
Thanks for contributing a merge request!
|
|
||||||
|
|
||||||
We recommend that first-time contributors read our [contribution guidelines](https://eigen.tuxfamily.org/index.php?title=Contributing_to_Eigen).
|
|
||||||
|
|
||||||
Before submitting the MR, please complete the following checks:
|
|
||||||
- Create one PR per feature or bugfix,
|
|
||||||
- Run the test suite to verify your changes.
|
|
||||||
See our [test guidelines](https://eigen.tuxfamily.org/index.php?title=Tests).
|
|
||||||
- Add tests to cover the bug addressed or any new feature.
|
|
||||||
- Document new features. If it is a substantial change, add it to the [Changelog](https://gitlab.com/libeigen/eigen/-/blob/master/CHANGELOG.md).
|
|
||||||
- Leave the following box checked when submitting: `Allow commits from members who can merge to the target branch`.
|
|
||||||
This allows us to rebase and merge your change.
|
|
||||||
|
|
||||||
Note that we are a team of volunteers; we appreciate your patience during the review process.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Description
|
|
||||||
<!--Please explain your changes.-->
|
|
||||||
|
|
||||||
%{first_multiline_commit}
|
|
||||||
|
|
||||||
### Reference issue
|
|
||||||
<!--
|
|
||||||
You can link to a specific issue using the gitlab syntax #<issue number>.
|
|
||||||
If the MR fixes an issue, write "Fixes #<issue number>" to have the issue automatically closed on merge.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Additional information
|
|
||||||
<!--Any additional information you think is important.-->
|
|
||||||
3
.hgeol
Normal file
3
.hgeol
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[patterns]
|
||||||
|
**.* = native
|
||||||
|
eigen_autoexp_part.dat = CRLF
|
||||||
32
.hgignore
Normal file
32
.hgignore
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
syntax: glob
|
||||||
|
qrc_*cxx
|
||||||
|
*.orig
|
||||||
|
*.pyc
|
||||||
|
*.diff
|
||||||
|
diff
|
||||||
|
*.save
|
||||||
|
save
|
||||||
|
*.old
|
||||||
|
*.gmo
|
||||||
|
*.qm
|
||||||
|
core
|
||||||
|
core.*
|
||||||
|
*.bak
|
||||||
|
*~
|
||||||
|
build*
|
||||||
|
*.moc.*
|
||||||
|
*.moc
|
||||||
|
ui_*
|
||||||
|
CMakeCache.txt
|
||||||
|
tags
|
||||||
|
.*.swp
|
||||||
|
activity.png
|
||||||
|
*.out
|
||||||
|
*.php*
|
||||||
|
*.log
|
||||||
|
*.orig
|
||||||
|
*.rej
|
||||||
|
log
|
||||||
|
patch
|
||||||
|
a
|
||||||
|
a.*
|
||||||
1935
CHANGELOG.md
1935
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
867
CMakeLists.txt
867
CMakeLists.txt
@@ -1,335 +1,85 @@
|
|||||||
cmake_minimum_required(VERSION 3.10.0)
|
project(Eigen)
|
||||||
|
|
||||||
#==============================================================================
|
cmake_minimum_required(VERSION 2.6.2)
|
||||||
# CMake Policy issues.
|
|
||||||
#==============================================================================
|
|
||||||
# Allow overriding options in a parent project via `set` before including Eigen.
|
|
||||||
if (POLICY CMP0077)
|
|
||||||
cmake_policy (SET CMP0077 NEW)
|
|
||||||
endif (POLICY CMP0077)
|
|
||||||
|
|
||||||
# NOTE Remove setting the policy once the minimum required CMake version is
|
# guard against in-source builds
|
||||||
# increased to at least 3.15. Retain enabling the export to package registry.
|
|
||||||
if (POLICY CMP0090)
|
|
||||||
# The export command does not populate package registry by default
|
|
||||||
cmake_policy (SET CMP0090 NEW)
|
|
||||||
# Unless otherwise specified, always export to package registry to ensure
|
|
||||||
# backwards compatibility.
|
|
||||||
if (NOT DEFINED CMAKE_EXPORT_PACKAGE_REGISTRY)
|
|
||||||
set (CMAKE_EXPORT_PACKAGE_REGISTRY ON)
|
|
||||||
endif (NOT DEFINED CMAKE_EXPORT_PACKAGE_REGISTRY)
|
|
||||||
endif (POLICY CMP0090)
|
|
||||||
|
|
||||||
# Disable warning about find_package(CUDA).
|
|
||||||
# CUDA language support is lacking for clang as the CUDA compiler
|
|
||||||
# until at least cmake version 3.18. Even then, there seems to be
|
|
||||||
# issues on Windows+Ninja in passing build flags. Continue using
|
|
||||||
# the "old" way for now.
|
|
||||||
if (POLICY CMP0146)
|
|
||||||
cmake_policy(SET CMP0146 OLD)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
# Normalize DESTINATION paths
|
|
||||||
if (POLICY CMP0177)
|
|
||||||
cmake_policy(SET CMP0177 NEW)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
# Respect <PackageName>_ROOT variables.
|
|
||||||
if (POLICY CMP0074)
|
|
||||||
cmake_policy(SET CMP0074 NEW)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
#==============================================================================
|
|
||||||
# CMake Project.
|
|
||||||
#==============================================================================
|
|
||||||
|
|
||||||
project(Eigen3)
|
|
||||||
|
|
||||||
# Remove this block after bumping CMake to v3.21.0
|
|
||||||
# PROJECT_IS_TOP_LEVEL is defined then by default
|
|
||||||
if(CMAKE_VERSION VERSION_LESS 3.21.0)
|
|
||||||
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
|
||||||
set(PROJECT_IS_TOP_LEVEL ON)
|
|
||||||
else()
|
|
||||||
set(PROJECT_IS_TOP_LEVEL OFF)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#==============================================================================
|
|
||||||
# Build ON/OFF Settings.
|
|
||||||
#==============================================================================
|
|
||||||
# Determine if we should build tests.
|
|
||||||
include(CMakeDependentOption)
|
|
||||||
cmake_dependent_option(BUILD_TESTING "Enable creation of tests." ON "PROJECT_IS_TOP_LEVEL" OFF)
|
|
||||||
option(EIGEN_BUILD_TESTING "Enable creation of Eigen tests." ${BUILD_TESTING})
|
|
||||||
option(EIGEN_LEAVE_TEST_IN_ALL_TARGET "Leaves tests in the all target, needed by ctest for automatic building." OFF)
|
|
||||||
|
|
||||||
# Determine if we should build BLAS/LAPACK implementations.
|
|
||||||
option(EIGEN_BUILD_BLAS "Toggles the building of the Eigen Blas library" ${PROJECT_IS_TOP_LEVEL})
|
|
||||||
option(EIGEN_BUILD_LAPACK "Toggles the building of the included Eigen LAPACK library" ${PROJECT_IS_TOP_LEVEL})
|
|
||||||
if (EIGEN_BUILD_BLAS OR EIGEN_BUILD_LAPACK)
|
|
||||||
# Determine if we should build shared libraries for BLAS/LAPACK on this platform.
|
|
||||||
if (NOT EIGEN_BUILD_SHARED_LIBS)
|
|
||||||
get_cmake_property(EIGEN_BUILD_SHARED_LIBS TARGET_SUPPORTS_SHARED_LIBS)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Avoid building docs if included from another project.
|
|
||||||
# Building documentation requires creating and running executables on the host
|
|
||||||
# platform. We shouldn't do this if cross-compiling.
|
|
||||||
if (PROJECT_IS_TOP_LEVEL AND NOT CMAKE_CROSSCOMPILING)
|
|
||||||
set(EIGEN_BUILD_DOC_DEFAULT ON)
|
|
||||||
endif()
|
|
||||||
option(EIGEN_BUILD_DOC "Enable creation of Eigen documentation" ${EIGEN_BUILD_DOC_DEFAULT})
|
|
||||||
|
|
||||||
option(EIGEN_BUILD_DEMOS "Toggles the building of the Eigen demos" ${PROJECT_IS_TOP_LEVEL})
|
|
||||||
|
|
||||||
# Disable pkgconfig only for native Windows builds
|
|
||||||
if(NOT WIN32 OR NOT CMAKE_HOST_SYSTEM_NAME MATCHES Windows)
|
|
||||||
option(EIGEN_BUILD_PKGCONFIG "Build pkg-config .pc file for Eigen" ${PROJECT_IS_TOP_LEVEL})
|
|
||||||
endif()
|
|
||||||
option(EIGEN_BUILD_CMAKE_PACKAGE "Enables the creation of EigenConfig.cmake and related files" ${PROJECT_IS_TOP_LEVEL})
|
|
||||||
|
|
||||||
if (EIGEN_BUILD_TESTING OR EIGEN_BUILD_BLAS OR EIGEN_BUILD_LAPACK OR EIGEN_BUILD_DOC OR EIGEN_BUILD_DEMOS)
|
|
||||||
set(EIGEN_IS_BUILDING_ ON)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#==============================================================================
|
|
||||||
# Version Info.
|
|
||||||
#==============================================================================
|
|
||||||
|
|
||||||
# If version information is not provided, automatically parse the version number
|
|
||||||
# from header files.
|
|
||||||
file(READ "${PROJECT_SOURCE_DIR}/Eigen/Version" _eigen_version_header)
|
|
||||||
if (NOT DEFINED EIGEN_WORLD_VERSION)
|
|
||||||
string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen_world_version_match "${_eigen_version_header}")
|
|
||||||
set(EIGEN_WORLD_VERSION "${CMAKE_MATCH_1}" CACHE STRING "")
|
|
||||||
endif()
|
|
||||||
if (NOT DEFINED EIGEN_MAJOR_VERSION)
|
|
||||||
string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen_major_version_match "${_eigen_version_header}")
|
|
||||||
set(EIGEN_MAJOR_VERSION "${CMAKE_MATCH_1}" CACHE STRING "")
|
|
||||||
endif()
|
|
||||||
if (NOT DEFINED EIGEN_MINOR_VERSION)
|
|
||||||
string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen_minor_version_match "${_eigen_version_header}")
|
|
||||||
set(EIGEN_MINOR_VERSION "${CMAKE_MATCH_1}" CACHE STRING "")
|
|
||||||
endif()
|
|
||||||
if (NOT DEFINED EIGEN_PATCH_VERSION)
|
|
||||||
string(REGEX MATCH "define[ \t]+EIGEN_PATCH_VERSION[ \t]+([0-9]+)" _eigen_patch_version_match "${_eigen_version_header}")
|
|
||||||
set(EIGEN_PATCH_VERSION "${CMAKE_MATCH_1}" CACHE STRING "")
|
|
||||||
endif()
|
|
||||||
if (NOT DEFINED EIGEN_PRERELEASE_VERSION)
|
|
||||||
set(EIGEN_PRERELEASE_VERSION "dev")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# If we are in a git repo, extract a changeset.
|
|
||||||
if(IS_DIRECTORY ${CMAKE_SOURCE_DIR}/.git)
|
|
||||||
# if the git program is absent or this will leave the EIGEN_GIT_REVNUM string empty,
|
|
||||||
# but won't stop CMake.
|
|
||||||
execute_process(COMMAND git ls-remote -q ${CMAKE_SOURCE_DIR} HEAD OUTPUT_VARIABLE EIGEN_GIT_OUTPUT)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# extract the git rev number from the git output...
|
|
||||||
if(EIGEN_GIT_OUTPUT)
|
|
||||||
string(REGEX MATCH "^([0-9;a-f]+).*" EIGEN_GIT_CHANGESET_MATCH "${EIGEN_GIT_OUTPUT}")
|
|
||||||
set(EIGEN_GIT_REVNUM "${CMAKE_MATCH_1}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (NOT DEFINED EIGEN_BUILD_VERSION AND DEFINED EIGEN_GIT_REVNUM)
|
|
||||||
string(SUBSTRING "${EIGEN_GIT_REVNUM}" 0 8 EIGEN_BUILD_VERSION)
|
|
||||||
else()
|
|
||||||
set(EIGEN_BUILD_VERSION "" CACHE STRING "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# The EIGEN_VERSION_NUMBER must be of the form <major.minor.patch>.
|
|
||||||
# The EIGEN_VERSION_STRING can contain the preprelease/build strings.
|
|
||||||
set(EIGEN_VERSION_NUMBER "${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION}.${EIGEN_PATCH_VERSION}" CACHE STRING "")
|
|
||||||
set(EIGEN_VERSION_STRING "${EIGEN_VERSION_NUMBER}" CACHE STRING "")
|
|
||||||
if (NOT "x${EIGEN_PRERELEASE_VERSION}" STREQUAL "x")
|
|
||||||
set(EIGEN_VERSION_STRING "${EIGEN_VERSION_STRING}-${EIGEN_PRERELEASE_VERSION}" CACHE STRING "")
|
|
||||||
endif()
|
|
||||||
if (NOT "x${EIGEN_BUILD_VERSION}" STREQUAL "x")
|
|
||||||
set(EIGEN_VERSION_STRING "${EIGEN_VERSION_STRING}+${EIGEN_BUILD_VERSION}" CACHE STRING "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
# Generate version file.
|
|
||||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/Version.in"
|
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/include/Eigen/Version")
|
|
||||||
|
|
||||||
#==============================================================================
|
|
||||||
# Install Path Configuration.
|
|
||||||
#==============================================================================
|
|
||||||
|
|
||||||
# Unconditionally allow install of targets to support nested dependency
|
|
||||||
# installations.
|
|
||||||
#
|
|
||||||
# Note: projects that depend on Eigen should _probably_ exclude installing
|
|
||||||
# Eigen by default (e.g. by using EXCLUDE_FROM_ALL when using
|
|
||||||
# FetchContent_Declare or add_subdirectory) to avoid overwriting a previous
|
|
||||||
# installation.
|
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
|
||||||
# Backward compatibility support for EIGEN_INCLUDE_INSTALL_DIR
|
|
||||||
if(EIGEN_INCLUDE_INSTALL_DIR)
|
|
||||||
message(WARNING "EIGEN_INCLUDE_INSTALL_DIR is deprecated. Use INCLUDE_INSTALL_DIR instead.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(EIGEN_INCLUDE_INSTALL_DIR AND NOT INCLUDE_INSTALL_DIR)
|
|
||||||
set(INCLUDE_INSTALL_DIR ${EIGEN_INCLUDE_INSTALL_DIR}
|
|
||||||
CACHE PATH "The directory relative to CMAKE_INSTALL_PREFIX where Eigen header files are installed")
|
|
||||||
else()
|
|
||||||
set(INCLUDE_INSTALL_DIR
|
|
||||||
"${CMAKE_INSTALL_INCLUDEDIR}/eigen3"
|
|
||||||
CACHE PATH "The directory relative to CMAKE_INSTALL_PREFIX where Eigen header files are installed"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
set(CMAKEPACKAGE_INSTALL_DIR
|
|
||||||
"${CMAKE_INSTALL_DATADIR}/eigen3/cmake"
|
|
||||||
CACHE PATH "The directory relative to CMAKE_INSTALL_PREFIX where Eigen3Config.cmake is installed"
|
|
||||||
)
|
|
||||||
set(PKGCONFIG_INSTALL_DIR
|
|
||||||
"${CMAKE_INSTALL_DATADIR}/pkgconfig"
|
|
||||||
CACHE PATH "The directory relative to CMAKE_INSTALL_PREFIX where eigen3.pc is installed"
|
|
||||||
)
|
|
||||||
|
|
||||||
foreach(var INCLUDE_INSTALL_DIR CMAKEPACKAGE_INSTALL_DIR PKGCONFIG_INSTALL_DIR)
|
|
||||||
# If an absolute path is specified, make it relative to "{CMAKE_INSTALL_PREFIX}".
|
|
||||||
if(IS_ABSOLUTE "${${var}}")
|
|
||||||
file(RELATIVE_PATH "${var}" "${CMAKE_INSTALL_PREFIX}" "${${var}}")
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
#==============================================================================
|
|
||||||
# Eigen Library.
|
|
||||||
#==============================================================================
|
|
||||||
|
|
||||||
# Alias Eigen_*_DIR to Eigen3_*_DIR:
|
|
||||||
set(Eigen_SOURCE_DIR ${Eigen3_SOURCE_DIR})
|
|
||||||
set(Eigen_BINARY_DIR ${Eigen3_BINARY_DIR})
|
|
||||||
|
|
||||||
# Imported target support
|
|
||||||
add_library (eigen INTERFACE)
|
|
||||||
add_library (Eigen3::Eigen ALIAS eigen)
|
|
||||||
target_include_directories (eigen INTERFACE
|
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
|
||||||
$<INSTALL_INTERFACE:${INCLUDE_INSTALL_DIR}>
|
|
||||||
)
|
|
||||||
|
|
||||||
# Eigen requires at least C++14
|
|
||||||
target_compile_features (eigen INTERFACE cxx_std_14)
|
|
||||||
|
|
||||||
# Export as title case Eigen
|
|
||||||
set_target_properties (eigen PROPERTIES EXPORT_NAME Eigen)
|
|
||||||
|
|
||||||
#==============================================================================
|
|
||||||
# Install Rule Configuration.
|
|
||||||
#==============================================================================
|
|
||||||
|
|
||||||
install(FILES
|
|
||||||
signature_of_eigen3_matrix_library
|
|
||||||
DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel
|
|
||||||
)
|
|
||||||
|
|
||||||
if(EIGEN_BUILD_PKGCONFIG)
|
|
||||||
configure_file(eigen3.pc.in eigen3.pc @ONLY)
|
|
||||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/eigen3.pc
|
|
||||||
DESTINATION ${PKGCONFIG_INSTALL_DIR})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
install(DIRECTORY Eigen DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel)
|
|
||||||
# Replace the "Version" header file with the generated one.
|
|
||||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/Eigen/Version
|
|
||||||
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/ COMPONENT Devel)
|
|
||||||
|
|
||||||
install(TARGETS eigen EXPORT Eigen3Targets)
|
|
||||||
|
|
||||||
if(EIGEN_BUILD_CMAKE_PACKAGE)
|
|
||||||
include (CMakePackageConfigHelpers)
|
|
||||||
configure_package_config_file (
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/cmake/Eigen3Config.cmake.in
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/Eigen3Config.cmake
|
|
||||||
INSTALL_DESTINATION ${CMAKEPACKAGE_INSTALL_DIR}
|
|
||||||
NO_SET_AND_CHECK_MACRO # Eigen does not provide legacy style defines
|
|
||||||
NO_CHECK_REQUIRED_COMPONENTS_MACRO # Eigen does not provide components
|
|
||||||
)
|
|
||||||
|
|
||||||
set(CVF_VERSION "${EIGEN_VERSION_NUMBER}")
|
|
||||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/Eigen3ConfigVersion.cmake.in"
|
|
||||||
"Eigen3ConfigVersion.cmake"
|
|
||||||
@ONLY)
|
|
||||||
|
|
||||||
# The Eigen target will be located in the Eigen3 namespace. Other CMake
|
|
||||||
# targets can refer to it using Eigen3::Eigen.
|
|
||||||
export (TARGETS eigen NAMESPACE Eigen3:: FILE Eigen3Targets.cmake)
|
|
||||||
# Export Eigen3 package to CMake registry such that it can be easily found by
|
|
||||||
# CMake even if it has not been installed to a standard directory.
|
|
||||||
export (PACKAGE Eigen3)
|
|
||||||
|
|
||||||
install (EXPORT Eigen3Targets NAMESPACE Eigen3:: DESTINATION ${CMAKEPACKAGE_INSTALL_DIR})
|
|
||||||
|
|
||||||
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/Eigen3Config.cmake
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/Eigen3ConfigVersion.cmake
|
|
||||||
DESTINATION ${CMAKEPACKAGE_INSTALL_DIR})
|
|
||||||
|
|
||||||
# Add uninstall target
|
|
||||||
if(NOT TARGET uninstall AND PROJECT_IS_TOP_LEVEL)
|
|
||||||
add_custom_target ( uninstall
|
|
||||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/EigenUninstall.cmake)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#==============================================================================
|
|
||||||
# General Build Configuration.
|
|
||||||
#==============================================================================
|
|
||||||
|
|
||||||
# Avoid setting the standard in a parent if unset.
|
|
||||||
if(PROJECT_IS_TOP_LEVEL)
|
|
||||||
set(CMAKE_CXX_STANDARD 14 CACHE STRING "Default C++ standard")
|
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON CACHE BOOL "Require C++ standard")
|
|
||||||
set(CMAKE_CXX_EXTENSIONS OFF CACHE BOOL "Allow C++ extensions")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Guard against in-source builds
|
|
||||||
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
|
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
|
||||||
message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there. You may need to remove CMakeCache.txt. ")
|
message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there. You may need to remove CMakeCache.txt. ")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Guard against bad build-type strings
|
# guard against bad build-type strings
|
||||||
if (PROJECT_IS_TOP_LEVEL AND NOT CMAKE_BUILD_TYPE)
|
|
||||||
|
if (NOT CMAKE_BUILD_TYPE)
|
||||||
set(CMAKE_BUILD_TYPE "Release")
|
set(CMAKE_BUILD_TYPE "Release")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Only try to figure out how to link the math library if we are building something.
|
string(TOLOWER "${CMAKE_BUILD_TYPE}" cmake_build_type_tolower)
|
||||||
# Otherwise, let the parent project deal with dependencies.
|
if( NOT cmake_build_type_tolower STREQUAL "debug"
|
||||||
if (EIGEN_IS_BUILDING_)
|
AND NOT cmake_build_type_tolower STREQUAL "release"
|
||||||
# Use Eigen's cmake files.
|
AND NOT cmake_build_type_tolower STREQUAL "relwithdebinfo")
|
||||||
|
message(FATAL_ERROR "Unknown build type \"${CMAKE_BUILD_TYPE}\". Allowed values are Debug, Release, RelWithDebInfo (case-insensitive).")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# retrieve version infomation #
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
# automatically parse the version number
|
||||||
|
file(READ "${PROJECT_SOURCE_DIR}/Eigen/src/Core/util/Macros.h" _eigen_version_header)
|
||||||
|
string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen_world_version_match "${_eigen_version_header}")
|
||||||
|
set(EIGEN_WORLD_VERSION "${CMAKE_MATCH_1}")
|
||||||
|
string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen_major_version_match "${_eigen_version_header}")
|
||||||
|
set(EIGEN_MAJOR_VERSION "${CMAKE_MATCH_1}")
|
||||||
|
string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen_minor_version_match "${_eigen_version_header}")
|
||||||
|
set(EIGEN_MINOR_VERSION "${CMAKE_MATCH_1}")
|
||||||
|
set(EIGEN_VERSION_NUMBER ${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION})
|
||||||
|
|
||||||
|
# if the mercurial program is absent, this will leave the EIGEN_HG_CHANGESET string empty,
|
||||||
|
# but won't stop CMake.
|
||||||
|
execute_process(COMMAND hg tip -R ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE EIGEN_HGTIP_OUTPUT)
|
||||||
|
execute_process(COMMAND hg branch -R ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE EIGEN_BRANCH_OUTPUT)
|
||||||
|
|
||||||
|
# if this is the default (aka development) branch, extract the mercurial changeset number from the hg tip output...
|
||||||
|
if(EIGEN_BRANCH_OUTPUT MATCHES "default")
|
||||||
|
string(REGEX MATCH "^changeset: *[0-9]*:([0-9;a-f]+).*" EIGEN_HG_CHANGESET_MATCH "${EIGEN_HGTIP_OUTPUT}")
|
||||||
|
set(EIGEN_HG_CHANGESET "${CMAKE_MATCH_1}")
|
||||||
|
endif(EIGEN_BRANCH_OUTPUT MATCHES "default")
|
||||||
|
#...and show it next to the version number
|
||||||
|
if(EIGEN_HG_CHANGESET)
|
||||||
|
set(EIGEN_VERSION "${EIGEN_VERSION_NUMBER} (mercurial changeset ${EIGEN_HG_CHANGESET})")
|
||||||
|
else(EIGEN_HG_CHANGESET)
|
||||||
|
set(EIGEN_VERSION "${EIGEN_VERSION_NUMBER}")
|
||||||
|
endif(EIGEN_HG_CHANGESET)
|
||||||
|
|
||||||
|
|
||||||
|
include(CheckCXXCompilerFlag)
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
||||||
|
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR OFF)
|
#############################################################################
|
||||||
|
# find how to link to the standard libraries #
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
find_package(StandardMathLibrary)
|
find_package(StandardMathLibrary)
|
||||||
find_package(AOCL QUIET)
|
|
||||||
set(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO "")
|
set(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO "")
|
||||||
if(AOCL_FOUND)
|
|
||||||
list(APPEND EIGEN_STANDARD_LIBRARIES_TO_LINK_TO ${AOCL_LIBRARIES})
|
|
||||||
if(AOCL_INCLUDE_DIRS)
|
|
||||||
include_directories(${AOCL_INCLUDE_DIRS})
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT STANDARD_MATH_LIBRARY_FOUND)
|
if(NOT STANDARD_MATH_LIBRARY_FOUND)
|
||||||
|
|
||||||
message(FATAL_ERROR
|
message(FATAL_ERROR
|
||||||
"Can't link to the standard math library. Please report to the Eigen developers, telling them about your platform.")
|
"Can't link to the standard math library. Please report to the Eigen developers, telling them about your platform.")
|
||||||
|
|
||||||
else()
|
else()
|
||||||
|
|
||||||
if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)
|
if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)
|
||||||
set(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO "${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO} ${STANDARD_MATH_LIBRARY}")
|
set(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO "${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO} ${STANDARD_MATH_LIBRARY}")
|
||||||
else()
|
else()
|
||||||
set(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO "${STANDARD_MATH_LIBRARY}")
|
set(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO "${STANDARD_MATH_LIBRARY}")
|
||||||
endif()
|
endif()
|
||||||
# Clean up any leading/trailing whitespace in the variable to avoid CMP0004 errors
|
|
||||||
string(STRIP "${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO}" EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)
|
if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)
|
||||||
message(STATUS "Standard libraries to link to explicitly: ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO}")
|
message(STATUS "Standard libraries to link to explicitly: ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO}")
|
||||||
@@ -337,112 +87,38 @@ if (EIGEN_IS_BUILDING_)
|
|||||||
message(STATUS "Standard libraries to link to explicitly: none")
|
message(STATUS "Standard libraries to link to explicitly: none")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Default tests/examples/libraries to row-major.
|
option(EIGEN_BUILD_BTL "Build benchmark suite" OFF)
|
||||||
|
if(NOT WIN32)
|
||||||
|
option(EIGEN_BUILD_PKGCONFIG "Build pkg-config .pc file for Eigen" ON)
|
||||||
|
endif(NOT WIN32)
|
||||||
|
|
||||||
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
|
||||||
|
option(EIGEN_SPLIT_LARGE_TESTS "Split large tests into smaller executables" ON)
|
||||||
|
|
||||||
option(EIGEN_DEFAULT_TO_ROW_MAJOR "Use row-major as default matrix storage order" OFF)
|
option(EIGEN_DEFAULT_TO_ROW_MAJOR "Use row-major as default matrix storage order" OFF)
|
||||||
if(EIGEN_DEFAULT_TO_ROW_MAJOR)
|
if(EIGEN_DEFAULT_TO_ROW_MAJOR)
|
||||||
add_definitions("-DEIGEN_DEFAULT_TO_ROW_MAJOR")
|
add_definitions("-DEIGEN_DEFAULT_TO_ROW_MAJOR")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
|
||||||
|
|
||||||
#==============================================================================
|
add_definitions("-DEIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS")
|
||||||
# Test Configuration.
|
|
||||||
#==============================================================================
|
|
||||||
|
|
||||||
if (EIGEN_BUILD_TESTING)
|
|
||||||
function(ei_maybe_separate_arguments variable mode args)
|
|
||||||
# Use separate_arguments if the input is a single string containing a space.
|
|
||||||
# Otherwise, if it is already a list or doesn't have a space, just propagate
|
|
||||||
# the original value. This is to better support multi-argument lists.
|
|
||||||
list(LENGTH args list_length)
|
|
||||||
if (${list_length} EQUAL 1)
|
|
||||||
string(FIND "${args}" " " has_space)
|
|
||||||
if (${has_space} GREATER -1)
|
|
||||||
separate_arguments(args ${mode} "${args}")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
set(${variable} ${args} PARENT_SCOPE)
|
|
||||||
endfunction(ei_maybe_separate_arguments)
|
|
||||||
|
|
||||||
include(CheckCXXCompilerFlag)
|
|
||||||
macro(ei_add_cxx_compiler_flag FLAG)
|
|
||||||
string(REGEX REPLACE "-" "" SFLAG1 ${FLAG})
|
|
||||||
string(REGEX REPLACE "\\+" "p" SFLAG ${SFLAG1})
|
|
||||||
check_cxx_compiler_flag(${FLAG} COMPILER_SUPPORT_${SFLAG})
|
|
||||||
if(COMPILER_SUPPORT_${SFLAG})
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAG}")
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
set(EIGEN_TEST_CUSTOM_LINKER_FLAGS "" CACHE STRING "Additional linker flags when linking unit tests.")
|
|
||||||
set(EIGEN_TEST_CUSTOM_CXX_FLAGS "" CACHE STRING "Additional compiler flags when compiling unit tests.")
|
|
||||||
# Convert space-separated arguments into CMake lists for downstream consumption.
|
|
||||||
ei_maybe_separate_arguments(EIGEN_TEST_CUSTOM_LINKER_FLAGS NATIVE_COMMAND "${EIGEN_TEST_CUSTOM_LINKER_FLAGS}")
|
|
||||||
ei_maybe_separate_arguments(EIGEN_TEST_CUSTOM_CXX_FLAGS NATIVE_COMMAND "${EIGEN_TEST_CUSTOM_CXX_FLAGS}")
|
|
||||||
|
|
||||||
option(EIGEN_SPLIT_LARGE_TESTS "Split large tests into smaller executables" ON)
|
|
||||||
set(EIGEN_TEST_MAX_SIZE "320" CACHE STRING "Maximal matrix/vector size, default is 320")
|
|
||||||
|
|
||||||
# Flags for tests.
|
|
||||||
if(NOT MSVC)
|
|
||||||
# We assume that other compilers are partly compatible with GNUCC
|
|
||||||
|
|
||||||
# clang outputs some warnings for unknown flags that are not caught by check_cxx_compiler_flag
|
|
||||||
# adding -Werror turns such warnings into errors
|
|
||||||
check_cxx_compiler_flag("-Werror" COMPILER_SUPPORT_WERROR)
|
|
||||||
if(COMPILER_SUPPORT_WERROR)
|
|
||||||
set(CMAKE_REQUIRED_FLAGS "-Werror")
|
|
||||||
endif()
|
|
||||||
ei_add_cxx_compiler_flag("-pedantic")
|
|
||||||
ei_add_cxx_compiler_flag("-Wall")
|
|
||||||
ei_add_cxx_compiler_flag("-Wextra")
|
|
||||||
# ei_add_cxx_compiler_flag("-Weverything") # clang
|
|
||||||
ei_add_cxx_compiler_flag("-Wundef")
|
|
||||||
ei_add_cxx_compiler_flag("-Wcast-align")
|
|
||||||
ei_add_cxx_compiler_flag("-Wchar-subscripts")
|
|
||||||
ei_add_cxx_compiler_flag("-Wnon-virtual-dtor")
|
|
||||||
ei_add_cxx_compiler_flag("-Wunused-local-typedefs")
|
|
||||||
ei_add_cxx_compiler_flag("-Wpointer-arith")
|
|
||||||
ei_add_cxx_compiler_flag("-Wwrite-strings")
|
|
||||||
ei_add_cxx_compiler_flag("-Wformat-security")
|
|
||||||
ei_add_cxx_compiler_flag("-Wshorten-64-to-32")
|
|
||||||
ei_add_cxx_compiler_flag("-Wlogical-op")
|
|
||||||
ei_add_cxx_compiler_flag("-Wenum-conversion")
|
|
||||||
ei_add_cxx_compiler_flag("-Wc++11-extensions")
|
|
||||||
ei_add_cxx_compiler_flag("-Wdouble-promotion")
|
|
||||||
# ei_add_cxx_compiler_flag("-Wconversion")
|
|
||||||
ei_add_cxx_compiler_flag("-Wshadow")
|
|
||||||
ei_add_cxx_compiler_flag("-Wno-psabi")
|
|
||||||
ei_add_cxx_compiler_flag("-Wno-variadic-macros")
|
|
||||||
ei_add_cxx_compiler_flag("-Wno-long-long")
|
|
||||||
ei_add_cxx_compiler_flag("-Wno-pass-failed") # disable clang's warning for unrolling when the loop count is dynamic.
|
|
||||||
ei_add_cxx_compiler_flag("-fno-common")
|
|
||||||
ei_add_cxx_compiler_flag("-fstrict-aliasing")
|
|
||||||
ei_add_cxx_compiler_flag("-wd981") # disable ICC's "operands are evaluated in unspecified order" remark
|
|
||||||
ei_add_cxx_compiler_flag("-wd2304") # disable ICC's "warning #2304: non-explicit constructor with single argument may cause implicit type conversion" produced by -Wnon-virtual-dtor
|
|
||||||
|
|
||||||
# Clang emits warnings about unused flag.
|
|
||||||
if (NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
|
||||||
ei_add_cxx_compiler_flag("-fno-check-new")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# GCC 12+ emits false-positive -Warray-bounds, -Wmaybe-uninitialized,
|
|
||||||
# -Wstringop-overread, and -Wnonnull warnings at -O2/-O3 in heavily
|
|
||||||
# templated code with mixed static/dynamic sizes. These are well-known
|
|
||||||
# compiler bugs (see GCC PR 109394, 106247, 105329, 98610, among others).
|
|
||||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
ei_add_cxx_compiler_flag("-Wno-array-bounds")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor -Wno-long-long -ansi -Wundef -Wcast-align -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -fexceptions -fno-check-new -fno-common -fstrict-aliasing")
|
||||||
ei_add_cxx_compiler_flag("-Wno-maybe-uninitialized")
|
set(CMAKE_CXX_FLAGS_DEBUG "-g3")
|
||||||
ei_add_cxx_compiler_flag("-Wno-stringop-overread")
|
set(CMAKE_CXX_FLAGS_RELEASE "-g0 -O2")
|
||||||
ei_add_cxx_compiler_flag("-Wno-nonnull")
|
|
||||||
|
check_cxx_compiler_flag("-Wno-variadic-macros" COMPILER_SUPPORT_WNOVARIADICMACRO)
|
||||||
|
if(COMPILER_SUPPORT_WNOVARIADICMACRO)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-variadic-macros")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
check_cxx_compiler_flag("-Wextra" COMPILER_SUPPORT_WEXTRA)
|
||||||
if(ANDROID_NDK)
|
if(COMPILER_SUPPORT_WEXTRA)
|
||||||
ei_add_cxx_compiler_flag("-pie")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra")
|
||||||
ei_add_cxx_compiler_flag("-fPIE")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_FLAGS "")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
|
||||||
|
|
||||||
option(EIGEN_TEST_SSE2 "Enable/Disable SSE2 in tests/examples" OFF)
|
option(EIGEN_TEST_SSE2 "Enable/Disable SSE2 in tests/examples" OFF)
|
||||||
if(EIGEN_TEST_SSE2)
|
if(EIGEN_TEST_SSE2)
|
||||||
@@ -474,101 +150,18 @@ if (EIGEN_BUILD_TESTING)
|
|||||||
message(STATUS "Enabling SSE4.2 in tests/examples")
|
message(STATUS "Enabling SSE4.2 in tests/examples")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
option(EIGEN_TEST_AVX "Enable/Disable AVX in tests/examples" OFF)
|
|
||||||
if(EIGEN_TEST_AVX)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx")
|
|
||||||
message(STATUS "Enabling AVX in tests/examples")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(EIGEN_TEST_FMA "Enable/Disable FMA in tests/examples" OFF)
|
|
||||||
if(EIGEN_TEST_FMA AND NOT EIGEN_TEST_NEON)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfma")
|
|
||||||
message(STATUS "Enabling FMA in tests/examples")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(EIGEN_TEST_AVX2 "Enable/Disable AVX2 in tests/examples" OFF)
|
|
||||||
if(EIGEN_TEST_AVX2)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx2 -mfma")
|
|
||||||
message(STATUS "Enabling AVX2 in tests/examples")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(EIGEN_TEST_AVX512 "Enable/Disable AVX512 in tests/examples" OFF)
|
|
||||||
if(EIGEN_TEST_AVX512)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx512f -mfma")
|
|
||||||
message(STATUS "Enabling AVX512 in tests/examples")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(EIGEN_TEST_AVX512DQ "Enable/Disable AVX512DQ in tests/examples" OFF)
|
|
||||||
if(EIGEN_TEST_AVX512DQ)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx512dq -mfma")
|
|
||||||
message(STATUS "Enabling AVX512DQ in tests/examples")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(EIGEN_TEST_AVX512FP16 "Enable/Disable AVX512-FP16 in tests/examples" OFF)
|
|
||||||
if(EIGEN_TEST_AVX512FP16)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx512f -mfma -mavx512vl -mavx512fp16")
|
|
||||||
message(STATUS "Enabling AVX512-FP16 in tests/examples")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(EIGEN_TEST_F16C "Enable/Disable F16C in tests/examples" OFF)
|
|
||||||
if(EIGEN_TEST_F16C)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mf16c")
|
|
||||||
message(STATUS "Enabling F16C in tests/examples")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(EIGEN_TEST_ALTIVEC "Enable/Disable AltiVec in tests/examples" OFF)
|
option(EIGEN_TEST_ALTIVEC "Enable/Disable AltiVec in tests/examples" OFF)
|
||||||
if(EIGEN_TEST_ALTIVEC)
|
if(EIGEN_TEST_ALTIVEC)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maltivec -mabi=altivec")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maltivec -mabi=altivec")
|
||||||
message(STATUS "Enabling AltiVec in tests/examples")
|
message(STATUS "Enabling AltiVec in tests/examples")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
option(EIGEN_TEST_VSX "Enable/Disable VSX in tests/examples" OFF)
|
|
||||||
if(EIGEN_TEST_VSX)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m64 -mvsx")
|
|
||||||
message(STATUS "Enabling VSX in tests/examples")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(EIGEN_TEST_MSA "Enable/Disable MSA in tests/examples" OFF)
|
|
||||||
if(EIGEN_TEST_MSA)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmsa")
|
|
||||||
message(STATUS "Enabling MSA in tests/examples")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(EIGEN_TEST_LSX "Enable/Disable LSX in tests/examples" OFF)
|
|
||||||
if(EIGEN_TEST_LSX)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mlsx")
|
|
||||||
message(STATUS "Enabling LSX in tests/examples")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(EIGEN_TEST_NEON "Enable/Disable Neon in tests/examples" OFF)
|
option(EIGEN_TEST_NEON "Enable/Disable Neon in tests/examples" OFF)
|
||||||
if(EIGEN_TEST_NEON)
|
if(EIGEN_TEST_NEON)
|
||||||
if(EIGEN_TEST_FMA)
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfloat-abi=softfp -mfpu=neon -mcpu=cortex-a8")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon-vfpv4")
|
|
||||||
else()
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon")
|
|
||||||
endif()
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfloat-abi=hard")
|
|
||||||
message(STATUS "Enabling NEON in tests/examples")
|
message(STATUS "Enabling NEON in tests/examples")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
option(EIGEN_TEST_NEON64 "Enable/Disable Neon in tests/examples" OFF)
|
|
||||||
if(EIGEN_TEST_NEON64)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
|
||||||
message(STATUS "Enabling NEON in tests/examples")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(EIGEN_TEST_Z13 "Enable/Disable S390X(zEC13) ZVECTOR in tests/examples" OFF)
|
|
||||||
if(EIGEN_TEST_Z13)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=z13 -mzvector")
|
|
||||||
message(STATUS "Enabling S390X(zEC13) ZVECTOR in tests/examples")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(EIGEN_TEST_Z14 "Enable/Disable S390X(zEC14) ZVECTOR in tests/examples" OFF)
|
|
||||||
if(EIGEN_TEST_Z14)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=z14 -mzvector")
|
|
||||||
message(STATUS "Enabling S390X(zEC13) ZVECTOR in tests/examples")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
check_cxx_compiler_flag("-fopenmp" COMPILER_SUPPORT_OPENMP)
|
check_cxx_compiler_flag("-fopenmp" COMPILER_SUPPORT_OPENMP)
|
||||||
if(COMPILER_SUPPORT_OPENMP)
|
if(COMPILER_SUPPORT_OPENMP)
|
||||||
option(EIGEN_TEST_OPENMP "Enable/Disable OpenMP in tests/examples" OFF)
|
option(EIGEN_TEST_OPENMP "Enable/Disable OpenMP in tests/examples" OFF)
|
||||||
@@ -578,14 +171,16 @@ if (EIGEN_BUILD_TESTING)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
else()
|
endif(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
|
|
||||||
|
if(MSVC)
|
||||||
# C4127 - conditional expression is constant
|
# C4127 - conditional expression is constant
|
||||||
# C4714 - marked as __forceinline not inlined (I failed to deactivate it selectively)
|
# C4714 - marked as __forceinline not inlined (I failed to deactivate it selectively)
|
||||||
# We can disable this warning in the unit tests since it is clear that it occurs
|
# We can disable this warning in the unit tests since it is clear that it occurs
|
||||||
# because we are oftentimes returning objects that have a destructor or may
|
# because we are oftentimes returning objects that have a destructor or may
|
||||||
# throw exceptions - in particular in the unit tests we are throwing extra many
|
# throw exceptions - in particular in the unit tests we are throwing extra many
|
||||||
# exceptions to cover indexing errors.
|
# exceptions to cover indexing errors.
|
||||||
# C4505 - unreferenced local function has been removed (impossible to deactivate selectively)
|
# C4505 - unreferenced local function has been removed (impossible to deactive selectively)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /wd4127 /wd4505 /wd4714")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /wd4127 /wd4505 /wd4714")
|
||||||
|
|
||||||
# replace all /Wx by /W4
|
# replace all /Wx by /W4
|
||||||
@@ -605,31 +200,10 @@ if (EIGEN_BUILD_TESTING)
|
|||||||
if(NOT CMAKE_CL_64)
|
if(NOT CMAKE_CL_64)
|
||||||
# arch is not supported on 64 bit systems, SSE is enabled automatically.
|
# arch is not supported on 64 bit systems, SSE is enabled automatically.
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:SSE2")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:SSE2")
|
||||||
endif()
|
endif(NOT CMAKE_CL_64)
|
||||||
message(STATUS "Enabling SSE2 in tests/examples")
|
message(STATUS "Enabling SSE2 in tests/examples")
|
||||||
endif()
|
endif(EIGEN_TEST_SSE2)
|
||||||
|
endif(MSVC)
|
||||||
option(EIGEN_TEST_AVX "Enable/Disable AVX in tests/examples" OFF)
|
|
||||||
if(EIGEN_TEST_AVX)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:AVX")
|
|
||||||
message(STATUS "Enabling AVX in tests/examples")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(EIGEN_TEST_FMA "Enable/Disable FMA/AVX2 in tests/examples" OFF)
|
|
||||||
option(EIGEN_TEST_AVX2 "Enable/Disable FMA/AVX2 in tests/examples" OFF)
|
|
||||||
if((EIGEN_TEST_FMA AND NOT EIGEN_TEST_NEON) OR EIGEN_TEST_AVX2)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:AVX2")
|
|
||||||
message(STATUS "Enabling FMA/AVX2 in tests/examples")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(EIGEN_TEST_AVX512 "Enable/Disable AVX512 in tests/examples" OFF)
|
|
||||||
option(EIGEN_TEST_AVX512DQ "Enable/Disable AVX512DQ in tests/examples" OFF)
|
|
||||||
if(EIGEN_TEST_AVX512 OR EIGEN_TEST_AVX512DQ)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:AVX512")
|
|
||||||
message(STATUS "Enabling AVX512 in tests/examples")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
endif(NOT MSVC)
|
|
||||||
|
|
||||||
option(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION "Disable explicit vectorization in tests/examples" OFF)
|
option(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION "Disable explicit vectorization in tests/examples" OFF)
|
||||||
option(EIGEN_TEST_X87 "Force using X87 instructions. Implies no vectorization." OFF)
|
option(EIGEN_TEST_X87 "Force using X87 instructions. Implies no vectorization." OFF)
|
||||||
@@ -665,156 +239,167 @@ if (EIGEN_BUILD_TESTING)
|
|||||||
message(STATUS "Disabling alignment in tests/examples")
|
message(STATUS "Disabling alignment in tests/examples")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
option(EIGEN_TEST_NO_EXCEPTIONS "Disables C++ exceptions" OFF)
|
option(EIGEN_TEST_C++0x "Enables all C++0x features." OFF)
|
||||||
if(EIGEN_TEST_NO_EXCEPTIONS)
|
|
||||||
ei_add_cxx_compiler_flag("-fno-exceptions")
|
|
||||||
message(STATUS "Disabling exceptions in tests/examples")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(EIGEN_CUDA_CXX_FLAGS "" CACHE STRING "Additional flags to pass to the cuda compiler.")
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
set(EIGEN_CUDA_COMPUTE_ARCH 30 CACHE STRING "The CUDA compute architecture(s) to target when compiling CUDA code")
|
|
||||||
|
|
||||||
option(EIGEN_TEST_SYCL "Add Sycl support." OFF)
|
# the user modifiable install path for header files
|
||||||
if(EIGEN_TEST_SYCL)
|
set(EIGEN_INCLUDE_INSTALL_DIR ${EIGEN_INCLUDE_INSTALL_DIR} CACHE PATH "The directory where we install the header files (optional)")
|
||||||
option(EIGEN_SYCL_DPCPP "Use the DPCPP Sycl implementation (DPCPP is default SYCL-Compiler)." ON)
|
|
||||||
option(EIGEN_SYCL_TRISYCL "Use the triSYCL Sycl implementation." OFF)
|
|
||||||
option(EIGEN_SYCL_ComputeCpp "Use the ComputeCPP Sycl implementation." OFF)
|
|
||||||
|
|
||||||
# Building options
|
# set the internal install path for header files which depends on wether the user modifiable
|
||||||
# https://developer.codeplay.com/products/computecpp/ce/2.11.0/guides/eigen-overview/options-for-building-eigen-sycl
|
# EIGEN_INCLUDE_INSTALL_DIR has been set by the user or not.
|
||||||
option(EIGEN_SYCL_USE_DEFAULT_SELECTOR "Use sycl default selector to select the preferred device." OFF)
|
if(EIGEN_INCLUDE_INSTALL_DIR)
|
||||||
option(EIGEN_SYCL_NO_LOCAL_MEM "Build for devices without dedicated shared memory." OFF)
|
set(INCLUDE_INSTALL_DIR
|
||||||
option(EIGEN_SYCL_LOCAL_MEM "Allow the use of local memory (enabled by default)." ON)
|
${EIGEN_INCLUDE_INSTALL_DIR}
|
||||||
option(EIGEN_SYCL_LOCAL_THREAD_DIM0 "Set work group size for dimension 0." 16)
|
CACHE INTERNAL
|
||||||
option(EIGEN_SYCL_LOCAL_THREAD_DIM1 "Set work group size for dimension 1." 16)
|
"The directory where we install the header files (internal)"
|
||||||
option(EIGEN_SYCL_ASYNC_EXECUTION "Allow asynchronous execution (enabled by default)." ON)
|
)
|
||||||
option(EIGEN_SYCL_DISABLE_SKINNY "Disable optimization for tall/skinny matrices." OFF)
|
else()
|
||||||
option(EIGEN_SYCL_DISABLE_DOUBLE_BUFFER "Disable double buffer." OFF)
|
set(INCLUDE_INSTALL_DIR
|
||||||
option(EIGEN_SYCL_DISABLE_SCALAR "Disable scalar contraction." OFF)
|
"${CMAKE_INSTALL_PREFIX}/include/eigen3"
|
||||||
option(EIGEN_SYCL_DISABLE_GEMV "Disable GEMV and create a single kernel to calculate contraction instead." OFF)
|
CACHE INTERNAL
|
||||||
|
"The directory where we install the header files (internal)"
|
||||||
set(EIGEN_SYCL ON)
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations -Wno-shorten-64-to-32 -Wno-cast-align")
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-copy-with-user-provided-copy -Wno-unused-variable")
|
|
||||||
set (CMAKE_MODULE_PATH "${CMAKE_ROOT}/Modules" "cmake/Modules/" "${CMAKE_MODULE_PATH}")
|
|
||||||
find_package(Threads REQUIRED)
|
|
||||||
if(EIGEN_SYCL_TRISYCL)
|
|
||||||
message(STATUS "Using triSYCL")
|
|
||||||
include(FindTriSYCL)
|
|
||||||
elseif(EIGEN_SYCL_ComputeCpp)
|
|
||||||
message(STATUS "Using ComputeCPP SYCL")
|
|
||||||
include(FindComputeCpp)
|
|
||||||
set(COMPUTECPP_DRIVER_DEFAULT_VALUE OFF)
|
|
||||||
if (NOT MSVC)
|
|
||||||
set(COMPUTECPP_DRIVER_DEFAULT_VALUE ON)
|
|
||||||
endif()
|
|
||||||
option(COMPUTECPP_USE_COMPILER_DRIVER
|
|
||||||
"Use ComputeCpp driver instead of a 2 steps compilation"
|
|
||||||
${COMPUTECPP_DRIVER_DEFAULT_VALUE}
|
|
||||||
)
|
)
|
||||||
else() #Default SYCL compiler is DPCPP (EIGEN_SYCL_DPCPP)
|
|
||||||
set(DPCPP_SYCL_TARGET "spir64" CACHE STRING "Default target for Intel CPU/GPU")
|
|
||||||
message(STATUS "Using DPCPP")
|
|
||||||
find_package(DPCPP)
|
|
||||||
add_definitions(-DSYCL_COMPILER_IS_DPCPP)
|
|
||||||
endif(EIGEN_SYCL_TRISYCL)
|
|
||||||
if(EIGEN_DONT_VECTORIZE_SYCL)
|
|
||||||
message(STATUS "Disabling SYCL vectorization in tests/examples")
|
|
||||||
# When disabling SYCL vectorization, also disable Eigen default vectorization
|
|
||||||
add_definitions(-DEIGEN_DONT_VECTORIZE=1)
|
|
||||||
add_definitions(-DEIGEN_DONT_VECTORIZE_SYCL=1)
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include(EigenConfigureTesting)
|
# similar to set_target_properties but append the property instead of overwriting it
|
||||||
|
macro(ei_add_target_property target prop value)
|
||||||
|
|
||||||
|
get_target_property(previous ${target} ${prop})
|
||||||
|
# if the property wasn't previously set, ${previous} is now "previous-NOTFOUND" which cmake allows catching with plain if()
|
||||||
|
if(NOT previous)
|
||||||
|
set(previous "")
|
||||||
|
endif(NOT previous)
|
||||||
|
set_target_properties(${target} PROPERTIES ${prop} "${previous} ${value}")
|
||||||
|
endmacro(ei_add_target_property)
|
||||||
|
|
||||||
|
install(FILES
|
||||||
|
signature_of_eigen3_matrix_library
|
||||||
|
DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel
|
||||||
|
)
|
||||||
|
|
||||||
|
if(EIGEN_BUILD_PKGCONFIG)
|
||||||
|
SET(path_separator ":")
|
||||||
|
STRING(REPLACE ${path_separator} ";" pkg_config_libdir_search "$ENV{PKG_CONFIG_LIBDIR}")
|
||||||
|
message(STATUS "searching for 'pkgconfig' directory in PKG_CONFIG_LIBDIR ( $ENV{PKG_CONFIG_LIBDIR} ), ${CMAKE_INSTALL_PREFIX}/share, and ${CMAKE_INSTALL_PREFIX}/lib")
|
||||||
|
FIND_PATH(pkg_config_libdir pkgconfig ${pkg_config_libdir_search} ${CMAKE_INSTALL_PREFIX}/share ${CMAKE_INSTALL_PREFIX}/lib ${pkg_config_libdir_search})
|
||||||
|
if(pkg_config_libdir)
|
||||||
|
SET(pkg_config_install_dir ${pkg_config_libdir})
|
||||||
|
message(STATUS "found ${pkg_config_libdir}/pkgconfig" )
|
||||||
|
else(pkg_config_libdir)
|
||||||
|
SET(pkg_config_install_dir ${CMAKE_INSTALL_PREFIX}/share)
|
||||||
|
message(STATUS "pkgconfig not found; installing in ${pkg_config_install_dir}" )
|
||||||
|
endif(pkg_config_libdir)
|
||||||
|
|
||||||
|
configure_file(eigen3.pc.in eigen3.pc)
|
||||||
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/eigen3.pc
|
||||||
|
DESTINATION ${pkg_config_install_dir}/pkgconfig
|
||||||
|
)
|
||||||
|
endif(EIGEN_BUILD_PKGCONFIG)
|
||||||
|
|
||||||
|
add_subdirectory(Eigen)
|
||||||
|
|
||||||
|
add_subdirectory(doc EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
add_custom_target(buildtests)
|
||||||
|
add_custom_target(check COMMAND "ctest")
|
||||||
|
add_dependencies(check buildtests)
|
||||||
|
|
||||||
|
# CMake/Ctest does not allow us to change the build command,
|
||||||
|
# so we have to workaround by directly editing the generated DartConfiguration.tcl file
|
||||||
|
# save CMAKE_MAKE_PROGRAM
|
||||||
|
set(CMAKE_MAKE_PROGRAM_SAVE ${CMAKE_MAKE_PROGRAM})
|
||||||
|
# and set a fake one
|
||||||
|
set(CMAKE_MAKE_PROGRAM "@EIGEN_MAKECOMMAND_PLACEHOLDER@")
|
||||||
|
|
||||||
|
include(CTest)
|
||||||
|
enable_testing() # must be called from the root CMakeLists, see man page
|
||||||
|
include(EigenTesting)
|
||||||
|
ei_init_testing()
|
||||||
|
|
||||||
|
# overwrite default DartConfiguration.tcl
|
||||||
|
# The worarounds are different for each version of the MSVC IDE
|
||||||
|
if(MSVC_IDE)
|
||||||
|
if(MSVC_VERSION EQUAL 1600) # MSVC 2010
|
||||||
|
set(EIGEN_MAKECOMMAND_PLACEHOLDER "${CMAKE_MAKE_PROGRAM_SAVE} buildtests.vcxproj /p:Configuration=\${CTEST_CONFIGURATION_TYPE} \n # ")
|
||||||
|
else() # MSVC 2008 (TODO check MSVC 2005)
|
||||||
|
set(EIGEN_MAKECOMMAND_PLACEHOLDER "${CMAKE_MAKE_PROGRAM_SAVE} /project buildtests")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
# for make and nmake
|
||||||
|
set(EIGEN_MAKECOMMAND_PLACEHOLDER "${CMAKE_MAKE_PROGRAM_SAVE} buildtests")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
configure_file(${CMAKE_BINARY_DIR}/DartConfiguration.tcl ${CMAKE_BINARY_DIR}/DartConfiguration.tcl)
|
||||||
|
# restore default CMAKE_MAKE_PROGRAM
|
||||||
|
set(CMAKE_MAKE_PROGRAM ${CMAKE_MAKE_PROGRAM_SAVE})
|
||||||
|
# un-set temporary variables so that it is like they never existed.
|
||||||
|
# CMake 2.6.3 introduces the more logical unset() syntax for this.
|
||||||
|
set(CMAKE_MAKE_PROGRAM_SAVE)
|
||||||
|
set(EIGEN_MAKECOMMAND_PLACEHOLDER)
|
||||||
|
|
||||||
|
configure_file(${CMAKE_SOURCE_DIR}/CTestCustom.cmake.in ${CMAKE_BINARY_DIR}/CTestCustom.cmake)
|
||||||
|
|
||||||
|
|
||||||
if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)
|
if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)
|
||||||
# CTest automatic test building relies on the "all" target.
|
add_subdirectory(test) # can't do EXCLUDE_FROM_ALL here, breaks CTest
|
||||||
add_subdirectory(test)
|
|
||||||
add_subdirectory(failtest)
|
|
||||||
else()
|
else()
|
||||||
add_subdirectory(test EXCLUDE_FROM_ALL)
|
add_subdirectory(test EXCLUDE_FROM_ALL)
|
||||||
add_subdirectory(failtest EXCLUDE_FROM_ALL)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(NOT MSVC)
|
||||||
|
if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)
|
||||||
|
add_subdirectory(blas)
|
||||||
|
add_subdirectory(lapack)
|
||||||
|
else()
|
||||||
|
add_subdirectory(blas EXCLUDE_FROM_ALL)
|
||||||
|
add_subdirectory(lapack EXCLUDE_FROM_ALL)
|
||||||
|
endif()
|
||||||
|
endif(NOT MSVC)
|
||||||
|
|
||||||
|
add_subdirectory(unsupported)
|
||||||
|
|
||||||
|
add_subdirectory(demos EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
# must be after test and unsupported, for configuring buildtests.in
|
||||||
|
add_subdirectory(scripts EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
# TODO: consider also replacing EIGEN_BUILD_BTL by a custom target "make btl"?
|
||||||
|
if(EIGEN_BUILD_BTL)
|
||||||
|
add_subdirectory(bench/btl EXCLUDE_FROM_ALL)
|
||||||
|
endif(EIGEN_BUILD_BTL)
|
||||||
|
|
||||||
ei_testing_print_summary()
|
ei_testing_print_summary()
|
||||||
|
|
||||||
if (EIGEN_SPLIT_TESTSUITE)
|
message(STATUS "")
|
||||||
ei_split_testsuite("${EIGEN_SPLIT_TESTSUITE}")
|
message(STATUS "Configured Eigen ${EIGEN_VERSION_NUMBER}")
|
||||||
endif()
|
message(STATUS "")
|
||||||
endif(EIGEN_BUILD_TESTING)
|
|
||||||
|
|
||||||
#==============================================================================
|
option(EIGEN_FAILTEST "Enable failtests." OFF)
|
||||||
# Other Build Configurations.
|
if(EIGEN_FAILTEST)
|
||||||
#==============================================================================
|
add_subdirectory(failtest)
|
||||||
add_subdirectory(unsupported)
|
|
||||||
|
|
||||||
if(EIGEN_BUILD_BLAS)
|
|
||||||
add_subdirectory(blas)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (EIGEN_BUILD_LAPACK)
|
|
||||||
add_subdirectory(lapack)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(EIGEN_BUILD_DOC)
|
|
||||||
add_subdirectory(doc EXCLUDE_FROM_ALL)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (EIGEN_BUILD_DEMOS)
|
|
||||||
add_subdirectory(demos EXCLUDE_FROM_ALL)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (PROJECT_IS_TOP_LEVEL)
|
|
||||||
# must be after test and unsupported, for configuring buildtests.in
|
|
||||||
add_subdirectory(scripts EXCLUDE_FROM_ALL)
|
|
||||||
configure_file(scripts/cdashtesting.cmake.in cdashtesting.cmake @ONLY)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#==============================================================================
|
|
||||||
# Summary.
|
|
||||||
#==============================================================================
|
|
||||||
|
|
||||||
if(PROJECT_IS_TOP_LEVEL)
|
|
||||||
string(TOLOWER "${CMAKE_GENERATOR}" cmake_generator_tolower)
|
string(TOLOWER "${CMAKE_GENERATOR}" cmake_generator_tolower)
|
||||||
if(cmake_generator_tolower MATCHES "makefile")
|
if(cmake_generator_tolower MATCHES "makefile")
|
||||||
message(STATUS "Available targets (use: make TARGET):")
|
message(STATUS "Some things you can do now:")
|
||||||
else()
|
message(STATUS "--------------+--------------------------------------------------------------")
|
||||||
message(STATUS "Available targets (use: cmake --build . --target TARGET):")
|
message(STATUS "Command | Description")
|
||||||
endif()
|
message(STATUS "--------------+--------------------------------------------------------------")
|
||||||
message(STATUS "------------+--------------------------------------------------------------")
|
message(STATUS "make install | Install to ${CMAKE_INSTALL_PREFIX}. To change that:")
|
||||||
message(STATUS "Target | Description")
|
message(STATUS " | cmake . -DCMAKE_INSTALL_PREFIX=yourpath")
|
||||||
message(STATUS "------------+--------------------------------------------------------------")
|
message(STATUS " | Eigen headers will then be installed to:")
|
||||||
message(STATUS "install | Install Eigen. Headers will be installed to:")
|
message(STATUS " | ${INCLUDE_INSTALL_DIR}")
|
||||||
message(STATUS " | <CMAKE_INSTALL_PREFIX>/<INCLUDE_INSTALL_DIR>")
|
message(STATUS " | To install Eigen headers to a separate location, do:")
|
||||||
message(STATUS " | Using the following values:")
|
message(STATUS " | cmake . -DEIGEN_INCLUDE_INSTALL_DIR=yourpath")
|
||||||
message(STATUS " | CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")
|
message(STATUS "make doc | Generate the API documentation, requires Doxygen & LaTeX")
|
||||||
message(STATUS " | INCLUDE_INSTALL_DIR: ${INCLUDE_INSTALL_DIR}")
|
message(STATUS "make check | Build and run the unit-tests. Read this page:")
|
||||||
message(STATUS " | Change the install location of Eigen headers using:")
|
|
||||||
message(STATUS " | cmake . -DCMAKE_INSTALL_PREFIX=yourprefix")
|
|
||||||
message(STATUS " | Or:")
|
|
||||||
message(STATUS " | cmake . -DINCLUDE_INSTALL_DIR=yourdir")
|
|
||||||
message(STATUS "uninstall | Remove files installed by the install target")
|
|
||||||
if (EIGEN_BUILD_DOC)
|
|
||||||
message(STATUS "doc | Generate the API documentation, requires Doxygen & LaTeX")
|
|
||||||
message(STATUS "install-doc | Install the API documentation")
|
|
||||||
endif()
|
|
||||||
if(EIGEN_BUILD_TESTING)
|
|
||||||
message(STATUS "check | Build and run the unit-tests. Read this page:")
|
|
||||||
message(STATUS " | http://eigen.tuxfamily.org/index.php?title=Tests")
|
message(STATUS " | http://eigen.tuxfamily.org/index.php?title=Tests")
|
||||||
endif()
|
message(STATUS "make blas | Build BLAS library (not the same thing as Eigen)")
|
||||||
if (EIGEN_BUILD_BLAS)
|
message(STATUS "--------------+--------------------------------------------------------------")
|
||||||
message(STATUS "blas | Build BLAS library (not the same thing as Eigen)")
|
else()
|
||||||
endif()
|
message(STATUS "To build/run the unit tests, read this page:")
|
||||||
if (EIGEN_BUILD_LAPACK)
|
message(STATUS " http://eigen.tuxfamily.org/index.php?title=Tests")
|
||||||
message(STATUS "lapack | Build LAPACK subset library (not the same thing as Eigen)")
|
|
||||||
endif()
|
|
||||||
message(STATUS "------------+--------------------------------------------------------------")
|
|
||||||
message(STATUS "")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
message(STATUS "")
|
message(STATUS "")
|
||||||
message(STATUS "Configured Eigen ${EIGEN_VERSION_STRING}")
|
|
||||||
message(STATUS "")
|
|
||||||
|
|
||||||
|
|||||||
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.
|
|
||||||
*/
|
|
||||||
26
COPYING.BSD
26
COPYING.BSD
@@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011, Intel Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
* Neither the name of Intel Corporation nor the names of its contributors may
|
|
||||||
be used to endorse or promote products derived from this software without
|
|
||||||
specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
674
COPYING.GPL
Normal file
674
COPYING.GPL
Normal file
@@ -0,0 +1,674 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
the GNU General Public License is intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users. We, the Free Software Foundation, use the
|
||||||
|
GNU General Public License for most of our software; it applies also to
|
||||||
|
any other work released this way by its authors. You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to prevent others from denying you
|
||||||
|
these rights or asking you to surrender the rights. Therefore, you have
|
||||||
|
certain responsibilities if you distribute copies of the software, or if
|
||||||
|
you modify it: responsibilities to respect the freedom of others.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must pass on to the recipients the same
|
||||||
|
freedoms that you received. You must make sure that they, too, receive
|
||||||
|
or can get the source code. And you must show them these terms so they
|
||||||
|
know their rights.
|
||||||
|
|
||||||
|
Developers that use the GNU GPL protect your rights with two steps:
|
||||||
|
(1) assert copyright on the software, and (2) offer you this License
|
||||||
|
giving you legal permission to copy, distribute and/or modify it.
|
||||||
|
|
||||||
|
For the developers' and authors' protection, the GPL clearly explains
|
||||||
|
that there is no warranty for this free software. For both users' and
|
||||||
|
authors' sake, the GPL requires that modified versions be marked as
|
||||||
|
changed, so that their problems will not be attributed erroneously to
|
||||||
|
authors of previous versions.
|
||||||
|
|
||||||
|
Some devices are designed to deny users access to install or run
|
||||||
|
modified versions of the software inside them, although the manufacturer
|
||||||
|
can do so. This is fundamentally incompatible with the aim of
|
||||||
|
protecting users' freedom to change the software. The systematic
|
||||||
|
pattern of such abuse occurs in the area of products for individuals to
|
||||||
|
use, which is precisely where it is most unacceptable. Therefore, we
|
||||||
|
have designed this version of the GPL to prohibit the practice for those
|
||||||
|
products. If such problems arise substantially in other domains, we
|
||||||
|
stand ready to extend this provision to those domains in future versions
|
||||||
|
of the GPL, as needed to protect the freedom of users.
|
||||||
|
|
||||||
|
Finally, every program is threatened constantly by software patents.
|
||||||
|
States should not allow patents to restrict development and use of
|
||||||
|
software on general-purpose computers, but in those that do, we wish to
|
||||||
|
avoid the special danger that patents applied to a free program could
|
||||||
|
make it effectively proprietary. To prevent this, the GPL assures that
|
||||||
|
patents cannot be used to render the program non-free.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Use with the GNU Affero General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU Affero General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the special requirements of the GNU Affero General Public License,
|
||||||
|
section 13, concerning interaction through a network will apply to the
|
||||||
|
combination as such.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies that a certain numbered version of the GNU General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program does terminal interaction, make it output a short
|
||||||
|
notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
|
<program> Copyright (C) <year> <name of author>
|
||||||
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, your program's commands
|
||||||
|
might be different; for a GUI interface, you would use an "about box".
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU GPL, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The GNU General Public License does not permit incorporating your program
|
||||||
|
into proprietary programs. If your program is a subroutine library, you
|
||||||
|
may consider it more useful to permit linking proprietary applications with
|
||||||
|
the library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License. But first, please read
|
||||||
|
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||||
165
COPYING.LGPL
Normal file
165
COPYING.LGPL
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
|
||||||
|
This version of the GNU Lesser General Public License incorporates
|
||||||
|
the terms and conditions of version 3 of the GNU General Public
|
||||||
|
License, supplemented by the additional permissions listed below.
|
||||||
|
|
||||||
|
0. Additional Definitions.
|
||||||
|
|
||||||
|
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||||
|
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
"The Library" refers to a covered work governed by this License,
|
||||||
|
other than an Application or a Combined Work as defined below.
|
||||||
|
|
||||||
|
An "Application" is any work that makes use of an interface provided
|
||||||
|
by the Library, but which is not otherwise based on the Library.
|
||||||
|
Defining a subclass of a class defined by the Library is deemed a mode
|
||||||
|
of using an interface provided by the Library.
|
||||||
|
|
||||||
|
A "Combined Work" is a work produced by combining or linking an
|
||||||
|
Application with the Library. The particular version of the Library
|
||||||
|
with which the Combined Work was made is also called the "Linked
|
||||||
|
Version".
|
||||||
|
|
||||||
|
The "Minimal Corresponding Source" for a Combined Work means the
|
||||||
|
Corresponding Source for the Combined Work, excluding any source code
|
||||||
|
for portions of the Combined Work that, considered in isolation, are
|
||||||
|
based on the Application, and not on the Linked Version.
|
||||||
|
|
||||||
|
The "Corresponding Application Code" for a Combined Work means the
|
||||||
|
object code and/or source code for the Application, including any data
|
||||||
|
and utility programs needed for reproducing the Combined Work from the
|
||||||
|
Application, but excluding the System Libraries of the Combined Work.
|
||||||
|
|
||||||
|
1. Exception to Section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
You may convey a covered work under sections 3 and 4 of this License
|
||||||
|
without being bound by section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
2. Conveying Modified Versions.
|
||||||
|
|
||||||
|
If you modify a copy of the Library, and, in your modifications, a
|
||||||
|
facility refers to a function or data to be supplied by an Application
|
||||||
|
that uses the facility (other than as an argument passed when the
|
||||||
|
facility is invoked), then you may convey a copy of the modified
|
||||||
|
version:
|
||||||
|
|
||||||
|
a) under this License, provided that you make a good faith effort to
|
||||||
|
ensure that, in the event an Application does not supply the
|
||||||
|
function or data, the facility still operates, and performs
|
||||||
|
whatever part of its purpose remains meaningful, or
|
||||||
|
|
||||||
|
b) under the GNU GPL, with none of the additional permissions of
|
||||||
|
this License applicable to that copy.
|
||||||
|
|
||||||
|
3. Object Code Incorporating Material from Library Header Files.
|
||||||
|
|
||||||
|
The object code form of an Application may incorporate material from
|
||||||
|
a header file that is part of the Library. You may convey such object
|
||||||
|
code under terms of your choice, provided that, if the incorporated
|
||||||
|
material is not limited to numerical parameters, data structure
|
||||||
|
layouts and accessors, or small macros, inline functions and templates
|
||||||
|
(ten or fewer lines in length), you do both of the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the object code that the
|
||||||
|
Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
4. Combined Works.
|
||||||
|
|
||||||
|
You may convey a Combined Work under terms of your choice that,
|
||||||
|
taken together, effectively do not restrict modification of the
|
||||||
|
portions of the Library contained in the Combined Work and reverse
|
||||||
|
engineering for debugging such modifications, if you also do each of
|
||||||
|
the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the Combined Work that
|
||||||
|
the Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
c) For a Combined Work that displays copyright notices during
|
||||||
|
execution, include the copyright notice for the Library among
|
||||||
|
these notices, as well as a reference directing the user to the
|
||||||
|
copies of the GNU GPL and this license document.
|
||||||
|
|
||||||
|
d) Do one of the following:
|
||||||
|
|
||||||
|
0) Convey the Minimal Corresponding Source under the terms of this
|
||||||
|
License, and the Corresponding Application Code in a form
|
||||||
|
suitable for, and under terms that permit, the user to
|
||||||
|
recombine or relink the Application with a modified version of
|
||||||
|
the Linked Version to produce a modified Combined Work, in the
|
||||||
|
manner specified by section 6 of the GNU GPL for conveying
|
||||||
|
Corresponding Source.
|
||||||
|
|
||||||
|
1) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (a) uses at run time
|
||||||
|
a copy of the Library already present on the user's computer
|
||||||
|
system, and (b) will operate properly with a modified version
|
||||||
|
of the Library that is interface-compatible with the Linked
|
||||||
|
Version.
|
||||||
|
|
||||||
|
e) Provide Installation Information, but only if you would otherwise
|
||||||
|
be required to provide such information under section 6 of the
|
||||||
|
GNU GPL, and only to the extent that such information is
|
||||||
|
necessary to install and execute a modified version of the
|
||||||
|
Combined Work produced by recombining or relinking the
|
||||||
|
Application with a modified version of the Linked Version. (If
|
||||||
|
you use option 4d0, the Installation Information must accompany
|
||||||
|
the Minimal Corresponding Source and Corresponding Application
|
||||||
|
Code. If you use option 4d1, you must provide the Installation
|
||||||
|
Information in the manner specified by section 6 of the GNU GPL
|
||||||
|
for conveying Corresponding Source.)
|
||||||
|
|
||||||
|
5. Combined Libraries.
|
||||||
|
|
||||||
|
You may place library facilities that are a work based on the
|
||||||
|
Library side by side in a single library together with other library
|
||||||
|
facilities that are not Applications and are not covered by this
|
||||||
|
License, and convey such a combined library under terms of your
|
||||||
|
choice, if you do both of the following:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based
|
||||||
|
on the Library, uncombined with any other library facilities,
|
||||||
|
conveyed under the terms of this License.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library that part of it
|
||||||
|
is a work based on the Library, and explaining where to find the
|
||||||
|
accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
6. Revised Versions of the GNU Lesser General Public License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the GNU Lesser General Public License from time to time. Such new
|
||||||
|
versions will be similar in spirit to the present version, but may
|
||||||
|
differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Library as you received it specifies that a certain numbered version
|
||||||
|
of the GNU Lesser General Public License "or any later version"
|
||||||
|
applies to it, you have the option of following the terms and
|
||||||
|
conditions either of that published version or of any later version
|
||||||
|
published by the Free Software Foundation. If the Library as you
|
||||||
|
received it does not specify a version number of the GNU Lesser
|
||||||
|
General Public License, you may choose any version of the GNU Lesser
|
||||||
|
General Public License ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Library as you received it specifies that a proxy can decide
|
||||||
|
whether future versions of the GNU Lesser General Public License shall
|
||||||
|
apply, that proxy's public statement of acceptance of any version is
|
||||||
|
permanent authorization for you to choose that version for the
|
||||||
|
Library.
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
Minpack Copyright Notice (1999) University of Chicago. All rights reserved
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or
|
|
||||||
without modification, are permitted provided that the
|
|
||||||
following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above
|
|
||||||
copyright notice, this list of conditions and the following
|
|
||||||
disclaimer.
|
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following
|
|
||||||
disclaimer in the documentation and/or other materials
|
|
||||||
provided with the distribution.
|
|
||||||
|
|
||||||
3. The end-user documentation included with the
|
|
||||||
redistribution, if any, must include the following
|
|
||||||
acknowledgment:
|
|
||||||
|
|
||||||
"This product includes software developed by the
|
|
||||||
University of Chicago, as Operator of Argonne National
|
|
||||||
Laboratory.
|
|
||||||
|
|
||||||
Alternately, this acknowledgment may appear in the software
|
|
||||||
itself, if and wherever such third-party acknowledgments
|
|
||||||
normally appear.
|
|
||||||
|
|
||||||
4. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS"
|
|
||||||
WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE
|
|
||||||
UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND
|
|
||||||
THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE
|
|
||||||
OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY
|
|
||||||
OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR
|
|
||||||
USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF
|
|
||||||
THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4)
|
|
||||||
DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION
|
|
||||||
UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL
|
|
||||||
BE CORRECTED.
|
|
||||||
|
|
||||||
5. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT
|
|
||||||
HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF
|
|
||||||
ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT,
|
|
||||||
INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF
|
|
||||||
ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF
|
|
||||||
PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER
|
|
||||||
SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE,
|
|
||||||
EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE
|
|
||||||
POSSIBILITY OF SUCH LOSS OR DAMAGES.
|
|
||||||
373
COPYING.MPL2
373
COPYING.MPL2
@@ -1,373 +0,0 @@
|
|||||||
Mozilla Public License Version 2.0
|
|
||||||
==================================
|
|
||||||
|
|
||||||
1. Definitions
|
|
||||||
--------------
|
|
||||||
|
|
||||||
1.1. "Contributor"
|
|
||||||
means each individual or legal entity that creates, contributes to
|
|
||||||
the creation of, or owns Covered Software.
|
|
||||||
|
|
||||||
1.2. "Contributor Version"
|
|
||||||
means the combination of the Contributions of others (if any) used
|
|
||||||
by a Contributor and that particular Contributor's Contribution.
|
|
||||||
|
|
||||||
1.3. "Contribution"
|
|
||||||
means Covered Software of a particular Contributor.
|
|
||||||
|
|
||||||
1.4. "Covered Software"
|
|
||||||
means Source Code Form to which the initial Contributor has attached
|
|
||||||
the notice in Exhibit A, the Executable Form of such Source Code
|
|
||||||
Form, and Modifications of such Source Code Form, in each case
|
|
||||||
including portions thereof.
|
|
||||||
|
|
||||||
1.5. "Incompatible With Secondary Licenses"
|
|
||||||
means
|
|
||||||
|
|
||||||
(a) that the initial Contributor has attached the notice described
|
|
||||||
in Exhibit B to the Covered Software; or
|
|
||||||
|
|
||||||
(b) that the Covered Software was made available under the terms of
|
|
||||||
version 1.1 or earlier of the License, but not also under the
|
|
||||||
terms of a Secondary License.
|
|
||||||
|
|
||||||
1.6. "Executable Form"
|
|
||||||
means any form of the work other than Source Code Form.
|
|
||||||
|
|
||||||
1.7. "Larger Work"
|
|
||||||
means a work that combines Covered Software with other material, in
|
|
||||||
a separate file or files, that is not Covered Software.
|
|
||||||
|
|
||||||
1.8. "License"
|
|
||||||
means this document.
|
|
||||||
|
|
||||||
1.9. "Licensable"
|
|
||||||
means having the right to grant, to the maximum extent possible,
|
|
||||||
whether at the time of the initial grant or subsequently, any and
|
|
||||||
all of the rights conveyed by this License.
|
|
||||||
|
|
||||||
1.10. "Modifications"
|
|
||||||
means any of the following:
|
|
||||||
|
|
||||||
(a) any file in Source Code Form that results from an addition to,
|
|
||||||
deletion from, or modification of the contents of Covered
|
|
||||||
Software; or
|
|
||||||
|
|
||||||
(b) any new file in Source Code Form that contains any Covered
|
|
||||||
Software.
|
|
||||||
|
|
||||||
1.11. "Patent Claims" of a Contributor
|
|
||||||
means any patent claim(s), including without limitation, method,
|
|
||||||
process, and apparatus claims, in any patent Licensable by such
|
|
||||||
Contributor that would be infringed, but for the grant of the
|
|
||||||
License, by the making, using, selling, offering for sale, having
|
|
||||||
made, import, or transfer of either its Contributions or its
|
|
||||||
Contributor Version.
|
|
||||||
|
|
||||||
1.12. "Secondary License"
|
|
||||||
means either the GNU General Public License, Version 2.0, the GNU
|
|
||||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
|
||||||
Public License, Version 3.0, or any later versions of those
|
|
||||||
licenses.
|
|
||||||
|
|
||||||
1.13. "Source Code Form"
|
|
||||||
means the form of the work preferred for making modifications.
|
|
||||||
|
|
||||||
1.14. "You" (or "Your")
|
|
||||||
means an individual or a legal entity exercising rights under this
|
|
||||||
License. For legal entities, "You" includes any entity that
|
|
||||||
controls, is controlled by, or is under common control with You. For
|
|
||||||
purposes of this definition, "control" means (a) the power, direct
|
|
||||||
or indirect, to cause the direction or management of such entity,
|
|
||||||
whether by contract or otherwise, or (b) ownership of more than
|
|
||||||
fifty percent (50%) of the outstanding shares or beneficial
|
|
||||||
ownership of such entity.
|
|
||||||
|
|
||||||
2. License Grants and Conditions
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
2.1. Grants
|
|
||||||
|
|
||||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
|
||||||
non-exclusive license:
|
|
||||||
|
|
||||||
(a) under intellectual property rights (other than patent or trademark)
|
|
||||||
Licensable by such Contributor to use, reproduce, make available,
|
|
||||||
modify, display, perform, distribute, and otherwise exploit its
|
|
||||||
Contributions, either on an unmodified basis, with Modifications, or
|
|
||||||
as part of a Larger Work; and
|
|
||||||
|
|
||||||
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
|
||||||
for sale, have made, import, and otherwise transfer either its
|
|
||||||
Contributions or its Contributor Version.
|
|
||||||
|
|
||||||
2.2. Effective Date
|
|
||||||
|
|
||||||
The licenses granted in Section 2.1 with respect to any Contribution
|
|
||||||
become effective for each Contribution on the date the Contributor first
|
|
||||||
distributes such Contribution.
|
|
||||||
|
|
||||||
2.3. Limitations on Grant Scope
|
|
||||||
|
|
||||||
The licenses granted in this Section 2 are the only rights granted under
|
|
||||||
this License. No additional rights or licenses will be implied from the
|
|
||||||
distribution or licensing of Covered Software under this License.
|
|
||||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
|
||||||
Contributor:
|
|
||||||
|
|
||||||
(a) for any code that a Contributor has removed from Covered Software;
|
|
||||||
or
|
|
||||||
|
|
||||||
(b) for infringements caused by: (i) Your and any other third party's
|
|
||||||
modifications of Covered Software, or (ii) the combination of its
|
|
||||||
Contributions with other software (except as part of its Contributor
|
|
||||||
Version); or
|
|
||||||
|
|
||||||
(c) under Patent Claims infringed by Covered Software in the absence of
|
|
||||||
its Contributions.
|
|
||||||
|
|
||||||
This License does not grant any rights in the trademarks, service marks,
|
|
||||||
or logos of any Contributor (except as may be necessary to comply with
|
|
||||||
the notice requirements in Section 3.4).
|
|
||||||
|
|
||||||
2.4. Subsequent Licenses
|
|
||||||
|
|
||||||
No Contributor makes additional grants as a result of Your choice to
|
|
||||||
distribute the Covered Software under a subsequent version of this
|
|
||||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
|
||||||
permitted under the terms of Section 3.3).
|
|
||||||
|
|
||||||
2.5. Representation
|
|
||||||
|
|
||||||
Each Contributor represents that the Contributor believes its
|
|
||||||
Contributions are its original creation(s) or it has sufficient rights
|
|
||||||
to grant the rights to its Contributions conveyed by this License.
|
|
||||||
|
|
||||||
2.6. Fair Use
|
|
||||||
|
|
||||||
This License is not intended to limit any rights You have under
|
|
||||||
applicable copyright doctrines of fair use, fair dealing, or other
|
|
||||||
equivalents.
|
|
||||||
|
|
||||||
2.7. Conditions
|
|
||||||
|
|
||||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
|
||||||
in Section 2.1.
|
|
||||||
|
|
||||||
3. Responsibilities
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
3.1. Distribution of Source Form
|
|
||||||
|
|
||||||
All distribution of Covered Software in Source Code Form, including any
|
|
||||||
Modifications that You create or to which You contribute, must be under
|
|
||||||
the terms of this License. You must inform recipients that the Source
|
|
||||||
Code Form of the Covered Software is governed by the terms of this
|
|
||||||
License, and how they can obtain a copy of this License. You may not
|
|
||||||
attempt to alter or restrict the recipients' rights in the Source Code
|
|
||||||
Form.
|
|
||||||
|
|
||||||
3.2. Distribution of Executable Form
|
|
||||||
|
|
||||||
If You distribute Covered Software in Executable Form then:
|
|
||||||
|
|
||||||
(a) such Covered Software must also be made available in Source Code
|
|
||||||
Form, as described in Section 3.1, and You must inform recipients of
|
|
||||||
the Executable Form how they can obtain a copy of such Source Code
|
|
||||||
Form by reasonable means in a timely manner, at a charge no more
|
|
||||||
than the cost of distribution to the recipient; and
|
|
||||||
|
|
||||||
(b) You may distribute such Executable Form under the terms of this
|
|
||||||
License, or sublicense it under different terms, provided that the
|
|
||||||
license for the Executable Form does not attempt to limit or alter
|
|
||||||
the recipients' rights in the Source Code Form under this License.
|
|
||||||
|
|
||||||
3.3. Distribution of a Larger Work
|
|
||||||
|
|
||||||
You may create and distribute a Larger Work under terms of Your choice,
|
|
||||||
provided that You also comply with the requirements of this License for
|
|
||||||
the Covered Software. If the Larger Work is a combination of Covered
|
|
||||||
Software with a work governed by one or more Secondary Licenses, and the
|
|
||||||
Covered Software is not Incompatible With Secondary Licenses, this
|
|
||||||
License permits You to additionally distribute such Covered Software
|
|
||||||
under the terms of such Secondary License(s), so that the recipient of
|
|
||||||
the Larger Work may, at their option, further distribute the Covered
|
|
||||||
Software under the terms of either this License or such Secondary
|
|
||||||
License(s).
|
|
||||||
|
|
||||||
3.4. Notices
|
|
||||||
|
|
||||||
You may not remove or alter the substance of any license notices
|
|
||||||
(including copyright notices, patent notices, disclaimers of warranty,
|
|
||||||
or limitations of liability) contained within the Source Code Form of
|
|
||||||
the Covered Software, except that You may alter any license notices to
|
|
||||||
the extent required to remedy known factual inaccuracies.
|
|
||||||
|
|
||||||
3.5. Application of Additional Terms
|
|
||||||
|
|
||||||
You may choose to offer, and to charge a fee for, warranty, support,
|
|
||||||
indemnity or liability obligations to one or more recipients of Covered
|
|
||||||
Software. However, You may do so only on Your own behalf, and not on
|
|
||||||
behalf of any Contributor. You must make it absolutely clear that any
|
|
||||||
such warranty, support, indemnity, or liability obligation is offered by
|
|
||||||
You alone, and You hereby agree to indemnify every Contributor for any
|
|
||||||
liability incurred by such Contributor as a result of warranty, support,
|
|
||||||
indemnity or liability terms You offer. You may include additional
|
|
||||||
disclaimers of warranty and limitations of liability specific to any
|
|
||||||
jurisdiction.
|
|
||||||
|
|
||||||
4. Inability to Comply Due to Statute or Regulation
|
|
||||||
---------------------------------------------------
|
|
||||||
|
|
||||||
If it is impossible for You to comply with any of the terms of this
|
|
||||||
License with respect to some or all of the Covered Software due to
|
|
||||||
statute, judicial order, or regulation then You must: (a) comply with
|
|
||||||
the terms of this License to the maximum extent possible; and (b)
|
|
||||||
describe the limitations and the code they affect. Such description must
|
|
||||||
be placed in a text file included with all distributions of the Covered
|
|
||||||
Software under this License. Except to the extent prohibited by statute
|
|
||||||
or regulation, such description must be sufficiently detailed for a
|
|
||||||
recipient of ordinary skill to be able to understand it.
|
|
||||||
|
|
||||||
5. Termination
|
|
||||||
--------------
|
|
||||||
|
|
||||||
5.1. The rights granted under this License will terminate automatically
|
|
||||||
if You fail to comply with any of its terms. However, if You become
|
|
||||||
compliant, then the rights granted under this License from a particular
|
|
||||||
Contributor are reinstated (a) provisionally, unless and until such
|
|
||||||
Contributor explicitly and finally terminates Your grants, and (b) on an
|
|
||||||
ongoing basis, if such Contributor fails to notify You of the
|
|
||||||
non-compliance by some reasonable means prior to 60 days after You have
|
|
||||||
come back into compliance. Moreover, Your grants from a particular
|
|
||||||
Contributor are reinstated on an ongoing basis if such Contributor
|
|
||||||
notifies You of the non-compliance by some reasonable means, this is the
|
|
||||||
first time You have received notice of non-compliance with this License
|
|
||||||
from such Contributor, and You become compliant prior to 30 days after
|
|
||||||
Your receipt of the notice.
|
|
||||||
|
|
||||||
5.2. If You initiate litigation against any entity by asserting a patent
|
|
||||||
infringement claim (excluding declaratory judgment actions,
|
|
||||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
|
||||||
directly or indirectly infringes any patent, then the rights granted to
|
|
||||||
You by any and all Contributors for the Covered Software under Section
|
|
||||||
2.1 of this License shall terminate.
|
|
||||||
|
|
||||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
|
||||||
end user license agreements (excluding distributors and resellers) which
|
|
||||||
have been validly granted by You or Your distributors under this License
|
|
||||||
prior to termination shall survive termination.
|
|
||||||
|
|
||||||
************************************************************************
|
|
||||||
* *
|
|
||||||
* 6. Disclaimer of Warranty *
|
|
||||||
* ------------------------- *
|
|
||||||
* *
|
|
||||||
* Covered Software is provided under this License on an "as is" *
|
|
||||||
* basis, without warranty of any kind, either expressed, implied, or *
|
|
||||||
* statutory, including, without limitation, warranties that the *
|
|
||||||
* Covered Software is free of defects, merchantable, fit for a *
|
|
||||||
* particular purpose or non-infringing. The entire risk as to the *
|
|
||||||
* quality and performance of the Covered Software is with You. *
|
|
||||||
* Should any Covered Software prove defective in any respect, You *
|
|
||||||
* (not any Contributor) assume the cost of any necessary servicing, *
|
|
||||||
* repair, or correction. This disclaimer of warranty constitutes an *
|
|
||||||
* essential part of this License. No use of any Covered Software is *
|
|
||||||
* authorized under this License except under this disclaimer. *
|
|
||||||
* *
|
|
||||||
************************************************************************
|
|
||||||
|
|
||||||
************************************************************************
|
|
||||||
* *
|
|
||||||
* 7. Limitation of Liability *
|
|
||||||
* -------------------------- *
|
|
||||||
* *
|
|
||||||
* Under no circumstances and under no legal theory, whether tort *
|
|
||||||
* (including negligence), contract, or otherwise, shall any *
|
|
||||||
* Contributor, or anyone who distributes Covered Software as *
|
|
||||||
* permitted above, be liable to You for any direct, indirect, *
|
|
||||||
* special, incidental, or consequential damages of any character *
|
|
||||||
* including, without limitation, damages for lost profits, loss of *
|
|
||||||
* goodwill, work stoppage, computer failure or malfunction, or any *
|
|
||||||
* and all other commercial damages or losses, even if such party *
|
|
||||||
* shall have been informed of the possibility of such damages. This *
|
|
||||||
* limitation of liability shall not apply to liability for death or *
|
|
||||||
* personal injury resulting from such party's negligence to the *
|
|
||||||
* extent applicable law prohibits such limitation. Some *
|
|
||||||
* jurisdictions do not allow the exclusion or limitation of *
|
|
||||||
* incidental or consequential damages, so this exclusion and *
|
|
||||||
* limitation may not apply to You. *
|
|
||||||
* *
|
|
||||||
************************************************************************
|
|
||||||
|
|
||||||
8. Litigation
|
|
||||||
-------------
|
|
||||||
|
|
||||||
Any litigation relating to this License may be brought only in the
|
|
||||||
courts of a jurisdiction where the defendant maintains its principal
|
|
||||||
place of business and such litigation shall be governed by laws of that
|
|
||||||
jurisdiction, without reference to its conflict-of-law provisions.
|
|
||||||
Nothing in this Section shall prevent a party's ability to bring
|
|
||||||
cross-claims or counter-claims.
|
|
||||||
|
|
||||||
9. Miscellaneous
|
|
||||||
----------------
|
|
||||||
|
|
||||||
This License represents the complete agreement concerning the subject
|
|
||||||
matter hereof. If any provision of this License is held to be
|
|
||||||
unenforceable, such provision shall be reformed only to the extent
|
|
||||||
necessary to make it enforceable. Any law or regulation which provides
|
|
||||||
that the language of a contract shall be construed against the drafter
|
|
||||||
shall not be used to construe this License against a Contributor.
|
|
||||||
|
|
||||||
10. Versions of the License
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
10.1. New Versions
|
|
||||||
|
|
||||||
Mozilla Foundation is the license steward. Except as provided in Section
|
|
||||||
10.3, no one other than the license steward has the right to modify or
|
|
||||||
publish new versions of this License. Each version will be given a
|
|
||||||
distinguishing version number.
|
|
||||||
|
|
||||||
10.2. Effect of New Versions
|
|
||||||
|
|
||||||
You may distribute the Covered Software under the terms of the version
|
|
||||||
of the License under which You originally received the Covered Software,
|
|
||||||
or under the terms of any subsequent version published by the license
|
|
||||||
steward.
|
|
||||||
|
|
||||||
10.3. Modified Versions
|
|
||||||
|
|
||||||
If you create software not governed by this License, and you want to
|
|
||||||
create a new license for such software, you may create and use a
|
|
||||||
modified version of this License if you rename the license and remove
|
|
||||||
any references to the name of the license steward (except to note that
|
|
||||||
such modified license differs from this License).
|
|
||||||
|
|
||||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
|
||||||
Licenses
|
|
||||||
|
|
||||||
If You choose to distribute Source Code Form that is Incompatible With
|
|
||||||
Secondary Licenses under the terms of this version of the License, the
|
|
||||||
notice described in Exhibit B of this License must be attached.
|
|
||||||
|
|
||||||
Exhibit A - Source Code Form License Notice
|
|
||||||
-------------------------------------------
|
|
||||||
|
|
||||||
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 https://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
If it is not possible or desirable to put the notice in a particular
|
|
||||||
file, then You may include the notice in a location (such as a LICENSE
|
|
||||||
file in a relevant directory) where a recipient would be likely to look
|
|
||||||
for such a notice.
|
|
||||||
|
|
||||||
You may add additional accurate notices of copyright ownership.
|
|
||||||
|
|
||||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
|
||||||
---------------------------------------------------------
|
|
||||||
|
|
||||||
This Source Code Form is "Incompatible With Secondary Licenses", as
|
|
||||||
defined by the Mozilla Public License, v. 2.0.
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
Eigen is primarily MPL2 licensed. See COPYING.MPL2 and these links:
|
|
||||||
http://www.mozilla.org/MPL/2.0/
|
|
||||||
http://www.mozilla.org/MPL/2.0/FAQ.html
|
|
||||||
|
|
||||||
Some files contain third-party code under BSD, LGPL, Apache, or other
|
|
||||||
MPL2-compatible licenses, hence the other COPYING.* files here.
|
|
||||||
|
|
||||||
Note that some optional external dependencies (e.g. FFTW, MPFR C++)
|
|
||||||
are distributed under different licenses, including the GPL. Refer to
|
|
||||||
the individual source files and their respective COPYING files for
|
|
||||||
details.
|
|
||||||
@@ -2,16 +2,12 @@
|
|||||||
## 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")
|
||||||
|
|
||||||
set(CTEST_DROP_METHOD "http")
|
set(CTEST_DROP_METHOD "http")
|
||||||
set(CTEST_DROP_SITE "my.cdash.org")
|
set(CTEST_DROP_SITE "manao.inria.fr")
|
||||||
set(CTEST_DROP_LOCATION "/submit.php?project=Eigen")
|
set(CTEST_DROP_LOCATION "/CDash/submit.php?project=Eigen")
|
||||||
set(CTEST_DROP_SITE_CDASH TRUE)
|
set(CTEST_DROP_SITE_CDASH TRUE)
|
||||||
#set(CTEST_PROJECT_SUBPROJECTS
|
|
||||||
#Official
|
|
||||||
#Unsupported
|
|
||||||
#)
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS "2000")
|
## A tribute to Dynamic!
|
||||||
set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS "2000")
|
set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS "33331")
|
||||||
list(APPEND CTEST_CUSTOM_ERROR_EXCEPTION @EIGEN_CTEST_ERROR_EXCEPTION@)
|
set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS "33331")
|
||||||
|
|||||||
@@ -1,52 +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_ACCELERATESUPPORT_MODULE_H
|
|
||||||
#define EIGEN_ACCELERATESUPPORT_MODULE_H
|
|
||||||
|
|
||||||
#include "SparseCore"
|
|
||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
|
||||||
|
|
||||||
/** \ingroup Support_modules
|
|
||||||
* \defgroup AccelerateSupport_Module AccelerateSupport module
|
|
||||||
*
|
|
||||||
* This module provides an interface to the Apple Accelerate library.
|
|
||||||
* It provides the seven following main factorization classes:
|
|
||||||
* - class AccelerateLLT: a Cholesky (LL^T) factorization.
|
|
||||||
* - class AccelerateLDLT: the default LDL^T factorization.
|
|
||||||
* - class AccelerateLDLTUnpivoted: a Cholesky-like LDL^T factorization with only 1x1 pivots and no pivoting
|
|
||||||
* - class AccelerateLDLTSBK: an LDL^T factorization with Supernode Bunch-Kaufman and static pivoting
|
|
||||||
* - class AccelerateLDLTTPP: an LDL^T factorization with full threshold partial pivoting
|
|
||||||
* - class AccelerateQR: a QR factorization
|
|
||||||
* - class AccelerateCholeskyAtA: a QR factorization without storing Q (equivalent to A^TA = R^T R)
|
|
||||||
*
|
|
||||||
* \code
|
|
||||||
* #include <Eigen/AccelerateSupport>
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* In order to use this module, the Accelerate headers must be accessible from
|
|
||||||
* the include paths, and your binary must be linked to the Accelerate framework.
|
|
||||||
* The Accelerate library is only available on Apple hardware.
|
|
||||||
*
|
|
||||||
* Note that many of the algorithms can be influenced by the UpLo template
|
|
||||||
* argument. All matrices are assumed to be symmetric. For example, the following
|
|
||||||
* creates an LDLT factorization where your matrix is symmetric (implicit) and
|
|
||||||
* uses the lower triangle:
|
|
||||||
*
|
|
||||||
* \code
|
|
||||||
* AccelerateLDLT<SparseMatrix<float>, Lower> ldlt;
|
|
||||||
* \endcode
|
|
||||||
*/
|
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/AccelerateSupport/AccelerateSupport.h"
|
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
|
||||||
|
|
||||||
#endif // EIGEN_ACCELERATESUPPORT_MODULE_H
|
|
||||||
11
Eigen/Array
Normal file
11
Eigen/Array
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#ifndef EIGEN_ARRAY_MODULE_H
|
||||||
|
#define EIGEN_ARRAY_MODULE_H
|
||||||
|
|
||||||
|
// include Core first to handle Eigen2 support macros
|
||||||
|
#include "Core"
|
||||||
|
|
||||||
|
#ifndef EIGEN2_SUPPORT
|
||||||
|
#error The Eigen/Array header does no longer exist in Eigen3. All that functionality has moved to Eigen/Core.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // EIGEN_ARRAY_MODULE_H
|
||||||
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
|
||||||
|
)
|
||||||
|
|
||||||
|
add_subdirectory(src)
|
||||||
@@ -1,41 +1,33 @@
|
|||||||
// 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_CHOLESKY_MODULE_H
|
#ifndef EIGEN_CHOLESKY_MODULE_H
|
||||||
#define EIGEN_CHOLESKY_MODULE_H
|
#define EIGEN_CHOLESKY_MODULE_H
|
||||||
|
|
||||||
#include "Core"
|
#include "Core"
|
||||||
#include "Jacobi"
|
|
||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
|
namespace Eigen {
|
||||||
|
|
||||||
/** \defgroup Cholesky_Module Cholesky module
|
/** \defgroup Cholesky_Module Cholesky module
|
||||||
|
*
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* This module provides two variants of the Cholesky decomposition for selfadjoint (hermitian) matrices.
|
* This module provides two variants of the Cholesky decomposition for selfadjoint (hermitian) matrices.
|
||||||
* Those decompositions are also accessible via the following methods:
|
* Those decompositions are accessible via the following MatrixBase methods:
|
||||||
* - MatrixBase::llt()
|
* - MatrixBase::llt(),
|
||||||
* - MatrixBase::ldlt()
|
* - MatrixBase::ldlt()
|
||||||
* - SelfAdjointView::llt()
|
|
||||||
* - SelfAdjointView::ldlt()
|
|
||||||
*
|
*
|
||||||
* \code
|
* \code
|
||||||
* #include <Eigen/Cholesky>
|
* #include <Eigen/Cholesky>
|
||||||
* \endcode
|
* \endcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
#include "src/misc/Solve.h"
|
||||||
#include "src/Cholesky/LLT.h"
|
#include "src/Cholesky/LLT.h"
|
||||||
#include "src/Cholesky/LDLT.h"
|
#include "src/Cholesky/LDLT.h"
|
||||||
#ifdef EIGEN_USE_LAPACKE
|
|
||||||
#include "src/misc/lapacke_helpers.h"
|
} // namespace Eigen
|
||||||
#include "src/Cholesky/LLT_LAPACKE.h"
|
|
||||||
#endif
|
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#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: */
|
||||||
|
|||||||
@@ -1,48 +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_CHOLMODSUPPORT_MODULE_H
|
|
||||||
#define EIGEN_CHOLMODSUPPORT_MODULE_H
|
|
||||||
|
|
||||||
#include "SparseCore"
|
|
||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
|
||||||
|
|
||||||
#include <cholmod.h>
|
|
||||||
|
|
||||||
/** \ingroup Support_modules
|
|
||||||
* \defgroup CholmodSupport_Module CholmodSupport module
|
|
||||||
*
|
|
||||||
* This module provides an interface to the Cholmod library which is part of the <a
|
|
||||||
* href="http://www.suitesparse.com">suitesparse</a> package. It provides the two following main factorization classes:
|
|
||||||
* - 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).
|
|
||||||
*
|
|
||||||
* For the sake of completeness, this module also propose the two following classes:
|
|
||||||
* - class CholmodSimplicialLLT
|
|
||||||
* - class CholmodSimplicialLDLT
|
|
||||||
* Note that these classes do not bring any particular advantage compared to the built-in
|
|
||||||
* SimplicialLLT and SimplicialLDLT factorization classes.
|
|
||||||
*
|
|
||||||
* \code
|
|
||||||
* #include <Eigen/CholmodSupport>
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* In order to use this module, the cholmod headers must be accessible from the include paths, and your binary must be
|
|
||||||
* linked to the cholmod library and its dependencies. The dependencies depend on how cholmod has been compiled. For a
|
|
||||||
* cmake based project, you can use our FindCholmod.cmake module to help you in this task.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/CholmodSupport/CholmodSupport.h"
|
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
|
||||||
|
|
||||||
#endif // EIGEN_CHOLMODSUPPORT_MODULE_H
|
|
||||||
521
Eigen/Core
521
Eigen/Core
@@ -4,58 +4,127 @@
|
|||||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
// Copyright (C) 2007-2011 Benoit Jacob <jacob.benoit.1@gmail.com>
|
// Copyright (C) 2007-2011 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_CORE_MODULE_H
|
#ifndef EIGEN_CORE_H
|
||||||
#define EIGEN_CORE_MODULE_H
|
#define EIGEN_CORE_H
|
||||||
|
|
||||||
// Eigen version information.
|
// first thing Eigen does: stop the compiler from committing suicide
|
||||||
#include "Version"
|
|
||||||
|
|
||||||
// first thing Eigen does: stop the compiler from reporting useless warnings.
|
|
||||||
#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
|
// 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 compiler/OS/arch detections and define most defaults.
|
// it's where we do all the alignment settings (platform detection and honoring the user's will if he
|
||||||
|
// defined e.g. EIGEN_DONT_ALIGN) so it needs to be done before we do anything with vectorization.
|
||||||
#include "src/Core/util/Macros.h"
|
#include "src/Core/util/Macros.h"
|
||||||
|
|
||||||
// This detects SSE/AVX/NEON/etc. and configure alignment settings
|
// if alignment is disabled, then disable vectorization. Note: EIGEN_ALIGN is the proper check, it takes into
|
||||||
#include "src/Core/util/ConfigureVectorization.h"
|
// account both the user's will (EIGEN_DONT_ALIGN) and our own platform checks
|
||||||
|
#if !EIGEN_ALIGN
|
||||||
// We need cuda_runtime.h/hip_runtime.h to ensure that
|
#ifndef EIGEN_DONT_VECTORIZE
|
||||||
// the EIGEN_USING_STD macro works properly on the device side
|
#define EIGEN_DONT_VECTORIZE
|
||||||
#if defined(EIGEN_CUDACC)
|
#endif
|
||||||
#include <cuda_runtime.h>
|
|
||||||
#elif defined(EIGEN_HIPCC)
|
|
||||||
#include <hip/hip_runtime.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EIGEN_EXCEPTIONS
|
#ifdef _MSC_VER
|
||||||
#include <new>
|
#include <malloc.h> // for _aligned_malloc -- need it regardless of whether vectorization is enabled
|
||||||
|
#if (_MSC_VER >= 1500) // 2008 or later
|
||||||
|
// Remember that usage of defined() in a #define is undefined by the standard.
|
||||||
|
// a user reported that in 64-bit mode, MSVC doesn't care to define _M_IX86_FP.
|
||||||
|
#if (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(_M_X64)
|
||||||
|
#define EIGEN_SSE2_ON_MSVC_2008_OR_LATER
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
// Remember that usage of defined() in a #define is undefined by the standard
|
||||||
|
#if (defined __SSE2__) && ( (!defined __GNUC__) || EIGEN_GNUC_AT_LEAST(4,2) )
|
||||||
|
#define EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Prevent ICC from specializing std::complex operators that silently fail
|
#ifndef EIGEN_DONT_VECTORIZE
|
||||||
// on device. This allows us to use our own device-compatible specializations
|
|
||||||
// instead.
|
#if defined (EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER)
|
||||||
#if EIGEN_COMP_ICC && defined(EIGEN_GPU_COMPILE_PHASE) && !defined(_OVERRIDE_COMPLEX_SPECIALIZATION_)
|
|
||||||
#define _OVERRIDE_COMPLEX_SPECIALIZATION_ 1
|
// 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
|
#endif
|
||||||
#include <complex>
|
#ifdef __SSSE3__
|
||||||
|
#define EIGEN_VECTORIZE_SSSE3
|
||||||
// this include file manages BLAS and MKL related macros
|
#endif
|
||||||
// and inclusion of their respective header files
|
#ifdef __SSE4_1__
|
||||||
#include "src/Core/util/MKL_support.h"
|
#define EIGEN_VECTORIZE_SSE4_1
|
||||||
#include "src/Core/util/AOCL_Support.h"
|
#endif
|
||||||
|
#ifdef __SSE4_2__
|
||||||
|
#define EIGEN_VECTORIZE_SSE4_2
|
||||||
#if defined(EIGEN_HAS_CUDA_FP16) || defined(EIGEN_HAS_HIP_FP16)
|
|
||||||
#define EIGEN_HAS_GPU_FP16
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(EIGEN_HAS_CUDA_BF16) || defined(EIGEN_HAS_HIP_BF16)
|
// include files
|
||||||
#define EIGEN_HAS_GPU_BF16
|
|
||||||
|
// This extern "C" works around a MINGW-w64 compilation issue
|
||||||
|
// https://sourceforge.net/tracker/index.php?func=detail&aid=3018394&group_id=202880&atid=983354
|
||||||
|
// In essence, intrin.h is included by windows.h and also declares intrinsics (just as emmintrin.h etc. below do).
|
||||||
|
// However, intrin.h uses an extern "C" declaration, and g++ thus complains of duplicate declarations
|
||||||
|
// with conflicting linkage. The linkage for intrinsics doesn't matter, but at that stage the compiler doesn't know;
|
||||||
|
// so, to avoid compile errors when windows.h is included after Eigen/Core, ensure intrinsics are extern "C" here too.
|
||||||
|
// notice that since these are C headers, the extern "C" is theoretically needed anyways.
|
||||||
|
extern "C" {
|
||||||
|
#include <emmintrin.h>
|
||||||
|
#include <xmmintrin.h>
|
||||||
|
#ifdef EIGEN_VECTORIZE_SSE3
|
||||||
|
#include <pmmintrin.h>
|
||||||
|
#endif
|
||||||
|
#ifdef EIGEN_VECTORIZE_SSSE3
|
||||||
|
#include <tmmintrin.h>
|
||||||
|
#endif
|
||||||
|
#ifdef EIGEN_VECTORIZE_SSE4_1
|
||||||
|
#include <smmintrin.h>
|
||||||
|
#endif
|
||||||
|
#ifdef EIGEN_VECTORIZE_SSE4_2
|
||||||
|
#include <nmmintrin.h>
|
||||||
|
#endif
|
||||||
|
} // end extern "C"
|
||||||
|
#elif defined __ALTIVEC__
|
||||||
|
#define EIGEN_VECTORIZE
|
||||||
|
#define EIGEN_VECTORIZE_ALTIVEC
|
||||||
|
#include <altivec.h>
|
||||||
|
// We need to #undef all these ugly tokens defined in <altivec.h>
|
||||||
|
// => use __vector instead of vector
|
||||||
|
#undef bool
|
||||||
|
#undef vector
|
||||||
|
#undef pixel
|
||||||
|
#elif defined __ARM_NEON__
|
||||||
|
#define EIGEN_VECTORIZE
|
||||||
|
#define EIGEN_VECTORIZE_NEON
|
||||||
|
#include <arm_neon.h>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined _OPENMP) && (!defined EIGEN_DONT_PARALLELIZE)
|
#if (defined _OPENMP) && (!defined EIGEN_DONT_PARALLELIZE)
|
||||||
@@ -63,11 +132,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EIGEN_HAS_OPENMP
|
#ifdef EIGEN_HAS_OPENMP
|
||||||
#include <atomic>
|
|
||||||
#include <omp.h>
|
#include <omp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !EIGEN_COMP_ARM
|
// MSVC for windows mobile does not have the errno.h file
|
||||||
|
#if !(defined(_MSC_VER) && defined(_WIN32_WCE)) && !defined(__ARMCC_VERSION)
|
||||||
#define EIGEN_HAS_ERRNO
|
#define EIGEN_HAS_ERRNO
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -77,11 +146,10 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <complex>
|
||||||
|
#include <cassert>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#ifndef EIGEN_NO_IO
|
|
||||||
#include <sstream>
|
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#endif
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
@@ -89,71 +157,85 @@
|
|||||||
// for min/max:
|
// for min/max:
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <memory>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
// for std::is_nothrow_move_assignable
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
// for std::this_thread::yield().
|
|
||||||
#if !defined(EIGEN_USE_BLAS) && (defined(EIGEN_HAS_OPENMP) || defined(EIGEN_GEMM_THREADPOOL))
|
|
||||||
#include <thread>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// for __cpp_lib feature test macros
|
|
||||||
#if defined(__has_include) && __has_include(<version>)
|
|
||||||
#include <version>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// for std::bit_cast()
|
|
||||||
#if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L
|
|
||||||
#include <bit>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// for outputting debug info
|
// for outputting debug info
|
||||||
#ifdef EIGEN_DEBUG_ASSIGN
|
#ifdef EIGEN_DEBUG_ASSIGN
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#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 defined(_MSC_VER) && (defined(_M_IX86)||defined(_M_X64))
|
||||||
#if EIGEN_COMP_MSVC && (EIGEN_ARCH_i386_OR_x86_64 || EIGEN_ARCH_ARM64)
|
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Required for querying cache sizes on Linux and macOS.
|
#if defined(_CPPUNWIND) || defined(__EXCEPTIONS)
|
||||||
#if EIGEN_OS_LINUX
|
#define EIGEN_EXCEPTIONS
|
||||||
#include <unistd.h>
|
|
||||||
#elif EIGEN_OS_MAC
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/sysctl.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(EIGEN_USE_SYCL)
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
#undef min
|
#include <new>
|
||||||
#undef max
|
|
||||||
#undef isnan
|
|
||||||
#undef isinf
|
|
||||||
#undef isfinite
|
|
||||||
#include <CL/sycl.hpp>
|
|
||||||
#include <map>
|
|
||||||
#include <thread>
|
|
||||||
#include <utility>
|
|
||||||
#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
|
#endif
|
||||||
|
|
||||||
|
// defined in bits/termios.h
|
||||||
|
#undef B0
|
||||||
|
|
||||||
|
/** \brief Namespace containing all symbols from the %Eigen library. */
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
using std::size_t;
|
inline static const char *SimdInstructionSetsInUse(void) {
|
||||||
using std::ptrdiff_t;
|
#if defined(EIGEN_VECTORIZE_SSE4_2)
|
||||||
|
return "SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2";
|
||||||
|
#elif defined(EIGEN_VECTORIZE_SSE4_1)
|
||||||
|
return "SSE, SSE2, SSE3, SSSE3, SSE4.1";
|
||||||
|
#elif defined(EIGEN_VECTORIZE_SSSE3)
|
||||||
|
return "SSE, SSE2, SSE3, SSSE3";
|
||||||
|
#elif defined(EIGEN_VECTORIZE_SSE3)
|
||||||
|
return "SSE, SSE2, SSE3";
|
||||||
|
#elif defined(EIGEN_VECTORIZE_SSE2)
|
||||||
|
return "SSE, SSE2";
|
||||||
|
#elif defined(EIGEN_VECTORIZE_ALTIVEC)
|
||||||
|
return "AltiVec";
|
||||||
|
#elif defined(EIGEN_VECTORIZE_NEON)
|
||||||
|
return "ARM NEON";
|
||||||
|
#else
|
||||||
|
return "None";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Eigen
|
#define STAGE10_FULL_EIGEN2_API 10
|
||||||
|
#define STAGE20_RESOLVE_API_CONFLICTS 20
|
||||||
|
#define STAGE30_FULL_EIGEN3_API 30
|
||||||
|
#define STAGE40_FULL_EIGEN3_STRICTNESS 40
|
||||||
|
#define STAGE99_NO_EIGEN2_SUPPORT 99
|
||||||
|
|
||||||
|
#if defined EIGEN2_SUPPORT_STAGE40_FULL_EIGEN3_STRICTNESS
|
||||||
|
#define EIGEN2_SUPPORT
|
||||||
|
#define EIGEN2_SUPPORT_STAGE STAGE40_FULL_EIGEN3_STRICTNESS
|
||||||
|
#elif defined EIGEN2_SUPPORT_STAGE30_FULL_EIGEN3_API
|
||||||
|
#define EIGEN2_SUPPORT
|
||||||
|
#define EIGEN2_SUPPORT_STAGE STAGE30_FULL_EIGEN3_API
|
||||||
|
#elif defined EIGEN2_SUPPORT_STAGE20_RESOLVE_API_CONFLICTS
|
||||||
|
#define EIGEN2_SUPPORT
|
||||||
|
#define EIGEN2_SUPPORT_STAGE STAGE20_RESOLVE_API_CONFLICTS
|
||||||
|
#elif defined EIGEN2_SUPPORT_STAGE10_FULL_EIGEN2_API
|
||||||
|
#define EIGEN2_SUPPORT
|
||||||
|
#define EIGEN2_SUPPORT_STAGE STAGE10_FULL_EIGEN2_API
|
||||||
|
#elif defined EIGEN2_SUPPORT
|
||||||
|
// default to stage 3, that's what it's always meant
|
||||||
|
#define EIGEN2_SUPPORT_STAGE30_FULL_EIGEN3_API
|
||||||
|
#define EIGEN2_SUPPORT_STAGE STAGE30_FULL_EIGEN3_API
|
||||||
|
#else
|
||||||
|
#define EIGEN2_SUPPORT_STAGE STAGE99_NO_EIGEN2_SUPPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef EIGEN2_SUPPORT
|
||||||
|
#undef minor
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// we use size_t frequently and we'll never remember to prepend it with std:: everytime just to
|
||||||
|
// ensure QNX/QCC support
|
||||||
|
using std::size_t;
|
||||||
|
// gcc 4.6.0 wants std:: for ptrdiff_t
|
||||||
|
using std::ptrdiff_t;
|
||||||
|
|
||||||
/** \defgroup Core_Module Core module
|
/** \defgroup Core_Module Core module
|
||||||
* This is the main module of Eigen providing dense matrix and vector support
|
* This is the main module of Eigen providing dense matrix and vector support
|
||||||
@@ -165,249 +247,86 @@ using std::ptrdiff_t;
|
|||||||
* \endcode
|
* \endcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef EIGEN_USE_LAPACKE
|
|
||||||
#ifdef EIGEN_USE_MKL
|
|
||||||
#include "mkl_lapacke.h"
|
|
||||||
#elif defined(EIGEN_LAPACKE_SYSTEM)
|
|
||||||
#include <lapacke.h>
|
|
||||||
#else
|
|
||||||
#include "src/misc/lapacke.h"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/Core/util/Constants.h"
|
#include "src/Core/util/Constants.h"
|
||||||
#include "src/Core/util/Meta.h"
|
|
||||||
#include "src/Core/util/Assert.h"
|
|
||||||
#include "src/Core/util/ForwardDeclarations.h"
|
#include "src/Core/util/ForwardDeclarations.h"
|
||||||
#include "src/Core/util/StaticAssert.h"
|
#include "src/Core/util/Meta.h"
|
||||||
#include "src/Core/util/XprHelper.h"
|
#include "src/Core/util/XprHelper.h"
|
||||||
|
#include "src/Core/util/StaticAssert.h"
|
||||||
#include "src/Core/util/Memory.h"
|
#include "src/Core/util/Memory.h"
|
||||||
#include "src/Core/util/IntegralConstant.h"
|
|
||||||
#include "src/Core/util/Serializer.h"
|
|
||||||
#include "src/Core/util/SymbolicIndex.h"
|
|
||||||
#include "src/Core/util/EmulateArray.h"
|
|
||||||
#include "src/Core/util/MoreMeta.h"
|
|
||||||
|
|
||||||
#include "src/Core/NumTraits.h"
|
#include "src/Core/NumTraits.h"
|
||||||
#include "src/Core/MathFunctions.h"
|
#include "src/Core/MathFunctions.h"
|
||||||
#include "src/Core/RandomImpl.h"
|
|
||||||
#include "src/Core/GenericPacketMath.h"
|
#include "src/Core/GenericPacketMath.h"
|
||||||
#include "src/Core/MathFunctionsImpl.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/GenericPacketMathFunctionsFwd.h"
|
|
||||||
|
|
||||||
#if defined(EIGEN_VECTORIZE_GENERIC) && !defined(EIGEN_DONT_VECTORIZE)
|
#if defined EIGEN_VECTORIZE_SSE
|
||||||
#include "src/Core/arch/clang/PacketMath.h"
|
|
||||||
#include "src/Core/arch/clang/TypeCasting.h"
|
|
||||||
#include "src/Core/arch/clang/Complex.h"
|
|
||||||
#include "src/Core/arch/clang/Reductions.h"
|
|
||||||
#include "src/Core/arch/clang/MathFunctions.h"
|
|
||||||
#else
|
|
||||||
#if defined EIGEN_VECTORIZE_AVX512
|
|
||||||
#include "src/Core/arch/SSE/PacketMath.h"
|
#include "src/Core/arch/SSE/PacketMath.h"
|
||||||
#include "src/Core/arch/SSE/Reductions.h"
|
|
||||||
#include "src/Core/arch/AVX/PacketMath.h"
|
|
||||||
#include "src/Core/arch/AVX/Reductions.h"
|
|
||||||
#include "src/Core/arch/AVX512/PacketMath.h"
|
|
||||||
#include "src/Core/arch/AVX512/Reductions.h"
|
|
||||||
#if defined EIGEN_VECTORIZE_AVX512FP16
|
|
||||||
#include "src/Core/arch/AVX512/PacketMathFP16.h"
|
|
||||||
#endif
|
|
||||||
#include "src/Core/arch/SSE/TypeCasting.h"
|
|
||||||
#include "src/Core/arch/AVX/TypeCasting.h"
|
|
||||||
#include "src/Core/arch/AVX512/TypeCasting.h"
|
|
||||||
#if defined EIGEN_VECTORIZE_AVX512FP16
|
|
||||||
#include "src/Core/arch/AVX512/TypeCastingFP16.h"
|
|
||||||
#endif
|
|
||||||
#include "src/Core/arch/SSE/Complex.h"
|
|
||||||
#include "src/Core/arch/AVX/Complex.h"
|
|
||||||
#include "src/Core/arch/AVX512/Complex.h"
|
|
||||||
#include "src/Core/arch/SSE/MathFunctions.h"
|
|
||||||
#include "src/Core/arch/AVX/MathFunctions.h"
|
|
||||||
#include "src/Core/arch/AVX512/MathFunctions.h"
|
|
||||||
#if defined EIGEN_VECTORIZE_AVX512FP16
|
|
||||||
#include "src/Core/arch/AVX512/MathFunctionsFP16.h"
|
|
||||||
#endif
|
|
||||||
#include "src/Core/arch/AVX512/TrsmKernel.h"
|
|
||||||
#elif defined EIGEN_VECTORIZE_AVX
|
|
||||||
// Use AVX for floats and doubles, SSE for integers
|
|
||||||
#include "src/Core/arch/SSE/PacketMath.h"
|
|
||||||
#include "src/Core/arch/SSE/Reductions.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/Reductions.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/AVX/MathFunctions.h"
|
|
||||||
#elif defined EIGEN_VECTORIZE_SSE
|
|
||||||
#include "src/Core/arch/SSE/PacketMath.h"
|
|
||||||
#include "src/Core/arch/SSE/Reductions.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"
|
||||||
#endif
|
#elif defined EIGEN_VECTORIZE_ALTIVEC
|
||||||
|
|
||||||
#if 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/TypeCasting.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/Complex.h"
|
#include "src/Core/arch/NEON/Complex.h"
|
||||||
#elif defined EIGEN_VECTORIZE_LSX
|
|
||||||
#include "src/Core/arch/LSX/PacketMath.h"
|
|
||||||
#include "src/Core/arch/LSX/TypeCasting.h"
|
|
||||||
#include "src/Core/arch/LSX/MathFunctions.h"
|
|
||||||
#include "src/Core/arch/LSX/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_RVV10
|
|
||||||
#include "src/Core/arch/RVV10/PacketMath.h"
|
|
||||||
#include "src/Core/arch/RVV10/PacketMath4.h"
|
|
||||||
#include "src/Core/arch/RVV10/PacketMath2.h"
|
|
||||||
#include "src/Core/arch/RVV10/TypeCasting.h"
|
|
||||||
#include "src/Core/arch/RVV10/MathFunctions.h"
|
|
||||||
#if defined EIGEN_VECTORIZE_RVV10FP16
|
|
||||||
#include "src/Core/arch/RVV10/PacketMathFP16.h"
|
|
||||||
#endif
|
#endif
|
||||||
#if defined EIGEN_VECTORIZE_RVV10BF16
|
|
||||||
#include "src/Core/arch/RVV10/PacketMathBF16.h"
|
|
||||||
#endif
|
|
||||||
#elif defined EIGEN_VECTORIZE_ZVECTOR
|
|
||||||
#include "src/Core/arch/ZVector/PacketMath.h"
|
|
||||||
#include "src/Core/arch/ZVector/MathFunctions.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"
|
|
||||||
#elif defined EIGEN_VECTORIZE_HVX
|
|
||||||
#include "src/Core/arch/HVX/PacketMath.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined EIGEN_VECTORIZE_GPU
|
|
||||||
#include "src/Core/arch/GPU/PacketMath.h"
|
|
||||||
#include "src/Core/arch/GPU/MathFunctions.h"
|
|
||||||
#include "src/Core/arch/GPU/TypeCasting.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(EIGEN_USE_SYCL)
|
|
||||||
#include "src/Core/arch/SYCL/InteropHeaders.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 // #ifndef EIGEN_VECTORIZE_GENERIC
|
|
||||||
|
|
||||||
#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.h"
|
||||||
#include "src/Core/functors/BinaryFunctors.h"
|
|
||||||
#include "src/Core/functors/UnaryFunctors.h"
|
|
||||||
#include "src/Core/functors/NullaryFunctors.h"
|
|
||||||
#include "src/Core/functors/StlFunctors.h"
|
|
||||||
#include "src/Core/functors/AssignmentFunctors.h"
|
|
||||||
|
|
||||||
// Specialized functors for GPU.
|
|
||||||
#ifdef EIGEN_GPUCC
|
|
||||||
#include "src/Core/arch/GPU/Complex.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Specializations of vectorized activation functions for NEON.
|
|
||||||
#ifdef EIGEN_VECTORIZE_NEON
|
|
||||||
#include "src/Core/arch/NEON/UnaryFunctors.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "src/Core/util/IndexedViewHelper.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"
|
||||||
#include "src/Core/EigenBase.h"
|
#include "src/Core/EigenBase.h"
|
||||||
|
|
||||||
#include "src/Core/Product.h"
|
#ifndef EIGEN_PARSED_BY_DOXYGEN // work around Doxygen bug triggered by Assign.h r814874
|
||||||
#include "src/Core/CoreEvaluators.h"
|
// at least confirmed with Doxygen 1.5.5 and 1.5.6
|
||||||
#include "src/Core/AssignEvaluator.h"
|
|
||||||
#include "src/Core/RealView.h"
|
|
||||||
#include "src/Core/Assign.h"
|
#include "src/Core/Assign.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "src/Core/ArrayBase.h"
|
|
||||||
#include "src/Core/util/BlasUtil.h"
|
#include "src/Core/util/BlasUtil.h"
|
||||||
#include "src/Core/DenseStorage.h"
|
#include "src/Core/DenseStorage.h"
|
||||||
#include "src/Core/NestByValue.h"
|
#include "src/Core/NestByValue.h"
|
||||||
|
#include "src/Core/ForceAlignedAccess.h"
|
||||||
#include "src/Core/ReturnByValue.h"
|
#include "src/Core/ReturnByValue.h"
|
||||||
#include "src/Core/NoAlias.h"
|
#include "src/Core/NoAlias.h"
|
||||||
#include "src/Core/PlainObjectBase.h"
|
#include "src/Core/PlainObjectBase.h"
|
||||||
#include "src/Core/Matrix.h"
|
#include "src/Core/Matrix.h"
|
||||||
#include "src/Core/Array.h"
|
#include "src/Core/Array.h"
|
||||||
#include "src/Core/Fill.h"
|
|
||||||
#include "src/Core/CwiseTernaryOp.h"
|
|
||||||
#include "src/Core/CwiseBinaryOp.h"
|
#include "src/Core/CwiseBinaryOp.h"
|
||||||
#include "src/Core/CwiseUnaryOp.h"
|
#include "src/Core/CwiseUnaryOp.h"
|
||||||
#include "src/Core/CwiseNullaryOp.h"
|
#include "src/Core/CwiseNullaryOp.h"
|
||||||
#include "src/Core/CwiseUnaryView.h"
|
#include "src/Core/CwiseUnaryView.h"
|
||||||
#include "src/Core/SelfCwiseBinaryOp.h"
|
#include "src/Core/SelfCwiseBinaryOp.h"
|
||||||
#include "src/Core/InnerProduct.h"
|
|
||||||
#include "src/Core/Dot.h"
|
#include "src/Core/Dot.h"
|
||||||
#include "src/Core/StableNorm.h"
|
#include "src/Core/StableNorm.h"
|
||||||
#include "src/Core/Stride.h"
|
|
||||||
#include "src/Core/MapBase.h"
|
#include "src/Core/MapBase.h"
|
||||||
|
#include "src/Core/Stride.h"
|
||||||
#include "src/Core/Map.h"
|
#include "src/Core/Map.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"
|
||||||
#include "src/Core/DiagonalProduct.h"
|
#include "src/Core/DiagonalProduct.h"
|
||||||
#include "src/Core/SkewSymmetricMatrix3.h"
|
|
||||||
#include "src/Core/Redux.h"
|
|
||||||
#include "src/Core/Visitor.h"
|
|
||||||
#include "src/Core/FindCoeff.h"
|
|
||||||
#include "src/Core/Fuzzy.h"
|
|
||||||
#include "src/Core/Swap.h"
|
|
||||||
#include "src/Core/CommaInitializer.h"
|
|
||||||
#include "src/Core/GeneralProduct.h"
|
|
||||||
#include "src/Core/Solve.h"
|
|
||||||
#include "src/Core/Inverse.h"
|
|
||||||
#include "src/Core/SolverBase.h"
|
|
||||||
#include "src/Core/PermutationMatrix.h"
|
#include "src/Core/PermutationMatrix.h"
|
||||||
#include "src/Core/Transpositions.h"
|
#include "src/Core/Transpositions.h"
|
||||||
|
#include "src/Core/Redux.h"
|
||||||
|
#include "src/Core/Visitor.h"
|
||||||
|
#include "src/Core/Fuzzy.h"
|
||||||
|
#include "src/Core/IO.h"
|
||||||
|
#include "src/Core/Swap.h"
|
||||||
|
#include "src/Core/CommaInitializer.h"
|
||||||
|
#include "src/Core/Flagged.h"
|
||||||
|
#include "src/Core/ProductBase.h"
|
||||||
|
#include "src/Core/Product.h"
|
||||||
#include "src/Core/TriangularMatrix.h"
|
#include "src/Core/TriangularMatrix.h"
|
||||||
#include "src/Core/SelfAdjointView.h"
|
#include "src/Core/SelfAdjointView.h"
|
||||||
#include "src/Core/products/GeneralBlockPanelKernel.h"
|
#include "src/Core/SolveTriangular.h"
|
||||||
#include "src/Core/DeviceWrapper.h"
|
|
||||||
#ifdef EIGEN_GEMM_THREADPOOL
|
|
||||||
#include "ThreadPool"
|
|
||||||
#endif
|
|
||||||
#include "src/Core/products/Parallelizer.h"
|
#include "src/Core/products/Parallelizer.h"
|
||||||
#include "src/Core/ProductEvaluators.h"
|
#include "src/Core/products/CoeffBasedProduct.h"
|
||||||
|
#include "src/Core/products/GeneralBlockPanelKernel.h"
|
||||||
#include "src/Core/products/GeneralMatrixVector.h"
|
#include "src/Core/products/GeneralMatrixVector.h"
|
||||||
#include "src/Core/products/GeneralMatrixMatrix.h"
|
#include "src/Core/products/GeneralMatrixMatrix.h"
|
||||||
#include "src/Core/SolveTriangular.h"
|
|
||||||
#include "src/Core/products/GeneralMatrixMatrixTriangular.h"
|
#include "src/Core/products/GeneralMatrixMatrixTriangular.h"
|
||||||
#include "src/Core/products/SelfadjointMatrixVector.h"
|
#include "src/Core/products/SelfadjointMatrixVector.h"
|
||||||
#include "src/Core/products/SelfadjointMatrixMatrix.h"
|
#include "src/Core/products/SelfadjointMatrixMatrix.h"
|
||||||
@@ -418,56 +337,24 @@ using std::ptrdiff_t;
|
|||||||
#include "src/Core/products/TriangularSolverMatrix.h"
|
#include "src/Core/products/TriangularSolverMatrix.h"
|
||||||
#include "src/Core/products/TriangularSolverVector.h"
|
#include "src/Core/products/TriangularSolverVector.h"
|
||||||
#include "src/Core/BandMatrix.h"
|
#include "src/Core/BandMatrix.h"
|
||||||
#include "src/Core/CoreIterators.h"
|
|
||||||
#include "src/Core/ConditionEstimator.h"
|
|
||||||
|
|
||||||
#if !defined(EIGEN_VECTORIZE_GENERIC)
|
|
||||||
#if defined(EIGEN_VECTORIZE_VSX)
|
|
||||||
#include "src/Core/arch/AltiVec/MatrixProduct.h"
|
|
||||||
#elif defined EIGEN_VECTORIZE_NEON
|
|
||||||
#include "src/Core/arch/NEON/GeneralBlockPanelKernel.h"
|
|
||||||
#elif defined EIGEN_VECTORIZE_LSX
|
|
||||||
#include "src/Core/arch/LSX/GeneralBlockPanelKernel.h"
|
|
||||||
#elif defined EIGEN_VECTORIZE_RVV10
|
|
||||||
#include "src/Core/arch/RVV10/GeneralBlockPanelKernel.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(EIGEN_VECTORIZE_AVX512)
|
|
||||||
#include "src/Core/arch/AVX512/GemmKernel.h"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#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/ArrayBase.h"
|
||||||
#include "src/Core/ArrayWrapper.h"
|
#include "src/Core/ArrayWrapper.h"
|
||||||
#include "src/Core/StlIterators.h"
|
|
||||||
|
|
||||||
#ifdef EIGEN_USE_BLAS
|
} // namespace Eigen
|
||||||
#include "src/Core/products/GeneralMatrixMatrix_BLAS.h"
|
|
||||||
#include "src/Core/products/GeneralMatrixVector_BLAS.h"
|
|
||||||
#include "src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h"
|
|
||||||
#include "src/Core/products/SelfadjointMatrixMatrix_BLAS.h"
|
|
||||||
#include "src/Core/products/SelfadjointMatrixVector_BLAS.h"
|
|
||||||
#include "src/Core/products/TriangularMatrixMatrix_BLAS.h"
|
|
||||||
#include "src/Core/products/TriangularMatrixVector_BLAS.h"
|
|
||||||
#include "src/Core/products/TriangularSolverMatrix_BLAS.h"
|
|
||||||
#endif // EIGEN_USE_BLAS
|
|
||||||
|
|
||||||
#ifdef EIGEN_USE_MKL_VML
|
|
||||||
#include "src/Core/Assign_MKL.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EIGEN_USE_AOCL_VML
|
|
||||||
#include "src/Core/Assign_AOCL.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "src/Core/GlobalFunctions.h"
|
#include "src/Core/GlobalFunctions.h"
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_CORE_MODULE_H
|
#ifdef EIGEN2_SUPPORT
|
||||||
|
#include "Eigen2Support"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // EIGEN_CORE_H
|
||||||
|
|||||||
12
Eigen/Dense
12
Eigen/Dense
@@ -1,13 +1,3 @@
|
|||||||
// 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_DENSE_MODULE_H
|
|
||||||
#define EIGEN_DENSE_MODULE_H
|
|
||||||
|
|
||||||
#include "Core"
|
#include "Core"
|
||||||
#include "LU"
|
#include "LU"
|
||||||
#include "Cholesky"
|
#include "Cholesky"
|
||||||
@@ -15,5 +5,3 @@
|
|||||||
#include "SVD"
|
#include "SVD"
|
||||||
#include "Geometry"
|
#include "Geometry"
|
||||||
#include "Eigenvalues"
|
#include "Eigenvalues"
|
||||||
|
|
||||||
#endif // EIGEN_DENSE_MODULE_H
|
|
||||||
|
|||||||
14
Eigen/Eigen
14
Eigen/Eigen
@@ -1,14 +1,2 @@
|
|||||||
// 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_EIGEN_MODULE_H
|
|
||||||
#define EIGEN_EIGEN_MODULE_H
|
|
||||||
|
|
||||||
#include "Dense"
|
#include "Dense"
|
||||||
#include "Sparse"
|
//#include "Sparse"
|
||||||
|
|
||||||
#endif // EIGEN_EIGEN_MODULE_H
|
|
||||||
|
|||||||
82
Eigen/Eigen2Support
Normal file
82
Eigen/Eigen2Support
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
|
// for linear algebra.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
|
//
|
||||||
|
// Eigen is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef EIGEN2SUPPORT_H
|
||||||
|
#define EIGEN2SUPPORT_H
|
||||||
|
|
||||||
|
#if (!defined(EIGEN2_SUPPORT)) || (!defined(EIGEN_CORE_H))
|
||||||
|
#error Eigen2 support must be enabled by defining EIGEN2_SUPPORT before including any Eigen header
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
|
namespace Eigen {
|
||||||
|
|
||||||
|
/** \defgroup Eigen2Support_Module Eigen2 support module
|
||||||
|
* This module provides a couple of deprecated functions improving the compatibility with Eigen2.
|
||||||
|
*
|
||||||
|
* To use it, define EIGEN2_SUPPORT before including any Eigen header
|
||||||
|
* \code
|
||||||
|
* #define EIGEN2_SUPPORT
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "src/Eigen2Support/Macros.h"
|
||||||
|
#include "src/Eigen2Support/Memory.h"
|
||||||
|
#include "src/Eigen2Support/Meta.h"
|
||||||
|
#include "src/Eigen2Support/Lazy.h"
|
||||||
|
#include "src/Eigen2Support/Cwise.h"
|
||||||
|
#include "src/Eigen2Support/CwiseOperators.h"
|
||||||
|
#include "src/Eigen2Support/TriangularSolver.h"
|
||||||
|
#include "src/Eigen2Support/Block.h"
|
||||||
|
#include "src/Eigen2Support/VectorBlock.h"
|
||||||
|
#include "src/Eigen2Support/Minor.h"
|
||||||
|
#include "src/Eigen2Support/MathFunctions.h"
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Eigen
|
||||||
|
|
||||||
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
|
// Eigen2 used to include iostream
|
||||||
|
#include<iostream>
|
||||||
|
|
||||||
|
#define USING_PART_OF_NAMESPACE_EIGEN \
|
||||||
|
EIGEN_USING_MATRIX_TYPEDEFS \
|
||||||
|
using Eigen::Matrix; \
|
||||||
|
using Eigen::MatrixBase; \
|
||||||
|
using Eigen::ei_random; \
|
||||||
|
using Eigen::ei_real; \
|
||||||
|
using Eigen::ei_imag; \
|
||||||
|
using Eigen::ei_conj; \
|
||||||
|
using Eigen::ei_abs; \
|
||||||
|
using Eigen::ei_abs2; \
|
||||||
|
using Eigen::ei_sqrt; \
|
||||||
|
using Eigen::ei_exp; \
|
||||||
|
using Eigen::ei_log; \
|
||||||
|
using Eigen::ei_sin; \
|
||||||
|
using Eigen::ei_cos;
|
||||||
|
|
||||||
|
#endif // EIGEN2SUPPORT_H
|
||||||
@@ -1,23 +1,20 @@
|
|||||||
// 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_EIGENVALUES_MODULE_H
|
#ifndef EIGEN_EIGENVALUES_MODULE_H
|
||||||
#define EIGEN_EIGENVALUES_MODULE_H
|
#define EIGEN_EIGENVALUES_MODULE_H
|
||||||
|
|
||||||
#include "Core"
|
#include "Core"
|
||||||
|
|
||||||
#include "Cholesky"
|
|
||||||
#include "LU"
|
|
||||||
#include "Geometry"
|
|
||||||
#include "Sparse" // Needed by ComplexQZ.
|
|
||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
|
#include "Cholesky"
|
||||||
|
#include "Jacobi"
|
||||||
|
#include "Householder"
|
||||||
|
#include "LU"
|
||||||
|
|
||||||
|
namespace Eigen {
|
||||||
|
|
||||||
/** \defgroup Eigenvalues_Module Eigenvalues module
|
/** \defgroup Eigenvalues_Module Eigenvalues module
|
||||||
|
*
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* This module mainly provides various eigenvalue solvers.
|
* This module mainly provides various eigenvalue solvers.
|
||||||
* This module also provides some MatrixBase methods, including:
|
* This module also provides some MatrixBase methods, including:
|
||||||
@@ -29,7 +26,6 @@
|
|||||||
* \endcode
|
* \endcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/Eigenvalues/Tridiagonalization.h"
|
#include "src/Eigenvalues/Tridiagonalization.h"
|
||||||
#include "src/Eigenvalues/RealSchur.h"
|
#include "src/Eigenvalues/RealSchur.h"
|
||||||
#include "src/Eigenvalues/EigenSolver.h"
|
#include "src/Eigenvalues/EigenSolver.h"
|
||||||
@@ -38,24 +34,11 @@
|
|||||||
#include "src/Eigenvalues/HessenbergDecomposition.h"
|
#include "src/Eigenvalues/HessenbergDecomposition.h"
|
||||||
#include "src/Eigenvalues/ComplexSchur.h"
|
#include "src/Eigenvalues/ComplexSchur.h"
|
||||||
#include "src/Eigenvalues/ComplexEigenSolver.h"
|
#include "src/Eigenvalues/ComplexEigenSolver.h"
|
||||||
#include "src/Eigenvalues/RealQZ.h"
|
|
||||||
#include "src/Eigenvalues/ComplexQZ.h"
|
|
||||||
#include "src/Eigenvalues/GeneralizedEigenSolver.h"
|
|
||||||
#include "src/Eigenvalues/MatrixBaseEigenvalues.h"
|
#include "src/Eigenvalues/MatrixBaseEigenvalues.h"
|
||||||
#ifdef EIGEN_USE_LAPACKE
|
|
||||||
#ifdef EIGEN_USE_MKL
|
} // namespace Eigen
|
||||||
#include "mkl_lapacke.h"
|
|
||||||
#elif defined(EIGEN_LAPACKE_SYSTEM)
|
|
||||||
#include <lapacke.h>
|
|
||||||
#else
|
|
||||||
#include "src/misc/lapacke.h"
|
|
||||||
#endif
|
|
||||||
#include "src/Eigenvalues/RealSchur_LAPACKE.h"
|
|
||||||
#include "src/Eigenvalues/ComplexSchur_LAPACKE.h"
|
|
||||||
#include "src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h"
|
|
||||||
#endif
|
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#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: */
|
||||||
|
|||||||
@@ -1,39 +1,41 @@
|
|||||||
// 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_GEOMETRY_MODULE_H
|
#ifndef EIGEN_GEOMETRY_MODULE_H
|
||||||
#define EIGEN_GEOMETRY_MODULE_H
|
#define EIGEN_GEOMETRY_MODULE_H
|
||||||
|
|
||||||
#include "Core"
|
#include "Core"
|
||||||
|
|
||||||
#include "SVD"
|
|
||||||
#include "LU"
|
|
||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
|
#include "SVD"
|
||||||
|
#include "LU"
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265358979323846
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Eigen {
|
||||||
|
|
||||||
/** \defgroup Geometry_Module Geometry module
|
/** \defgroup Geometry_Module Geometry module
|
||||||
|
*
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* This module provides support for:
|
* This module provides support for:
|
||||||
* - fixed-size homogeneous transformations
|
* - fixed-size homogeneous transformations
|
||||||
* - translation, scaling, 2D and 3D rotations
|
* - translation, scaling, 2D and 3D rotations
|
||||||
* - \link Quaternion quaternions \endlink
|
* - quaternions
|
||||||
* - cross products (\ref MatrixBase::cross(), \ref MatrixBase::cross3())
|
* - \ref MatrixBase::cross() "cross product"
|
||||||
* - orthogonal vector generation (MatrixBase::unitOrthogonal)
|
* - \ref MatrixBase::unitOrthogonal() "orthognal vector generation"
|
||||||
* - some linear components: \link ParametrizedLine parametrized-lines \endlink and \link Hyperplane hyperplanes \endlink
|
* - some linear components: parametrized-lines and hyperplanes
|
||||||
* - \link AlignedBox axis aligned bounding boxes \endlink
|
*
|
||||||
* - \link umeyama() least-square transformation fitting \endlink
|
|
||||||
* \code
|
* \code
|
||||||
* #include <Eigen/Geometry>
|
* #include <Eigen/Geometry>
|
||||||
* \endcode
|
* \endcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/Geometry/OrthoMethods.h"
|
#include "src/Geometry/OrthoMethods.h"
|
||||||
#include "src/Geometry/EulerAngles.h"
|
#include "src/Geometry/EulerAngles.h"
|
||||||
|
|
||||||
|
#if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS
|
||||||
#include "src/Geometry/Homogeneous.h"
|
#include "src/Geometry/Homogeneous.h"
|
||||||
#include "src/Geometry/RotationBase.h"
|
#include "src/Geometry/RotationBase.h"
|
||||||
#include "src/Geometry/Rotation2D.h"
|
#include "src/Geometry/Rotation2D.h"
|
||||||
@@ -47,15 +49,19 @@
|
|||||||
#include "src/Geometry/AlignedBox.h"
|
#include "src/Geometry/AlignedBox.h"
|
||||||
#include "src/Geometry/Umeyama.h"
|
#include "src/Geometry/Umeyama.h"
|
||||||
|
|
||||||
#ifndef EIGEN_VECTORIZE_GENERIC
|
#if defined EIGEN_VECTORIZE_SSE
|
||||||
// TODO(rmlarsen): Make these work with generic vectorization if possible.
|
#include "src/Geometry/arch/Geometry_SSE.h"
|
||||||
// Use the SSE optimized version whenever possible.
|
|
||||||
#if (defined EIGEN_VECTORIZE_SSE) || (defined EIGEN_VECTORIZE_NEON)
|
|
||||||
#include "src/Geometry/arch/Geometry_SIMD.h"
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
#ifdef EIGEN2_SUPPORT
|
||||||
|
#include "src/Eigen2Support/Geometry/All.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace Eigen
|
||||||
|
|
||||||
#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: */
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,3 @@
|
|||||||
// 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_HOUSEHOLDER_MODULE_H
|
#ifndef EIGEN_HOUSEHOLDER_MODULE_H
|
||||||
#define EIGEN_HOUSEHOLDER_MODULE_H
|
#define EIGEN_HOUSEHOLDER_MODULE_H
|
||||||
|
|
||||||
@@ -12,6 +5,8 @@
|
|||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
|
namespace Eigen {
|
||||||
|
|
||||||
/** \defgroup Householder_Module Householder module
|
/** \defgroup Householder_Module Householder module
|
||||||
* This module provides Householder transformations.
|
* This module provides Householder transformations.
|
||||||
*
|
*
|
||||||
@@ -20,12 +15,13 @@
|
|||||||
* \endcode
|
* \endcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/Householder/Householder.h"
|
#include "src/Householder/Householder.h"
|
||||||
#include "src/Householder/BlockHouseholder.h"
|
|
||||||
#include "src/Householder/HouseholderSequence.h"
|
#include "src/Householder/HouseholderSequence.h"
|
||||||
// IWYU pragma: end_exports
|
#include "src/Householder/BlockHouseholder.h"
|
||||||
|
|
||||||
|
} // namespace Eigen
|
||||||
|
|
||||||
#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: */
|
||||||
|
|||||||
@@ -1,52 +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_ITERATIVELINEARSOLVERS_MODULE_H
|
|
||||||
#define EIGEN_ITERATIVELINEARSOLVERS_MODULE_H
|
|
||||||
|
|
||||||
#include "SparseCore"
|
|
||||||
#include "OrderingMethods"
|
|
||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \defgroup IterativeLinearSolvers_Module IterativeLinearSolvers module
|
|
||||||
*
|
|
||||||
* This module currently provides iterative methods to solve problems of the form \c A \c x = \c b, where \c A is a
|
|
||||||
squared matrix, usually very large and sparse.
|
|
||||||
* Those solvers are accessible via the following classes:
|
|
||||||
* - ConjugateGradient for selfadjoint (hermitian) matrices,
|
|
||||||
* - LeastSquaresConjugateGradient for rectangular least-square problems,
|
|
||||||
* - BiCGSTAB for general square matrices.
|
|
||||||
*
|
|
||||||
* These iterative solvers are associated with some preconditioners:
|
|
||||||
* - IdentityPreconditioner - not really useful
|
|
||||||
* - DiagonalPreconditioner - also called Jacobi preconditioner, work very well on diagonal dominant matrices.
|
|
||||||
* - IncompleteLUT - incomplete LU factorization with dual thresholding
|
|
||||||
*
|
|
||||||
* Such problems can also be solved using the direct sparse decomposition modules: SparseCholesky, CholmodSupport,
|
|
||||||
UmfPackSupport, SuperLUSupport, AccelerateSupport.
|
|
||||||
*
|
|
||||||
\code
|
|
||||||
#include <Eigen/IterativeLinearSolvers>
|
|
||||||
\endcode
|
|
||||||
*/
|
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/IterativeLinearSolvers/SolveWithGuess.h"
|
|
||||||
#include "src/IterativeLinearSolvers/IterativeSolverBase.h"
|
|
||||||
#include "src/IterativeLinearSolvers/BasicPreconditioners.h"
|
|
||||||
#include "src/IterativeLinearSolvers/ConjugateGradient.h"
|
|
||||||
#include "src/IterativeLinearSolvers/LeastSquareConjugateGradient.h"
|
|
||||||
#include "src/IterativeLinearSolvers/BiCGSTAB.h"
|
|
||||||
#include "src/IterativeLinearSolvers/IncompleteLUT.h"
|
|
||||||
#include "src/IterativeLinearSolvers/IncompleteCholesky.h"
|
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
|
||||||
|
|
||||||
#endif // EIGEN_ITERATIVELINEARSOLVERS_MODULE_H
|
|
||||||
15
Eigen/Jacobi
15
Eigen/Jacobi
@@ -1,10 +1,3 @@
|
|||||||
// 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_JACOBI_MODULE_H
|
#ifndef EIGEN_JACOBI_MODULE_H
|
||||||
#define EIGEN_JACOBI_MODULE_H
|
#define EIGEN_JACOBI_MODULE_H
|
||||||
|
|
||||||
@@ -12,6 +5,8 @@
|
|||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
|
namespace Eigen {
|
||||||
|
|
||||||
/** \defgroup Jacobi_Module Jacobi module
|
/** \defgroup Jacobi_Module Jacobi module
|
||||||
* This module provides Jacobi and Givens rotations.
|
* This module provides Jacobi and Givens rotations.
|
||||||
*
|
*
|
||||||
@@ -24,10 +19,12 @@
|
|||||||
* - MatrixBase::applyOnTheRight().
|
* - MatrixBase::applyOnTheRight().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/Jacobi/Jacobi.h"
|
#include "src/Jacobi/Jacobi.h"
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
} // namespace Eigen
|
||||||
|
|
||||||
#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,43 +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 "SparseCore"
|
|
||||||
|
|
||||||
#include "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 KLU has been compiled. For a
|
|
||||||
* cmake based project, you can use our FindKLU.cmake module to help you in this task.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/KLUSupport/KLUSupport.h"
|
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
|
||||||
|
|
||||||
#endif // EIGEN_KLUSUPPORT_MODULE_H
|
|
||||||
31
Eigen/LU
31
Eigen/LU
@@ -1,10 +1,3 @@
|
|||||||
// 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_LU_MODULE_H
|
#ifndef EIGEN_LU_MODULE_H
|
||||||
#define EIGEN_LU_MODULE_H
|
#define EIGEN_LU_MODULE_H
|
||||||
|
|
||||||
@@ -12,6 +5,8 @@
|
|||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
|
namespace Eigen {
|
||||||
|
|
||||||
/** \defgroup LU_Module LU module
|
/** \defgroup LU_Module LU module
|
||||||
* This module includes %LU decomposition and related notions such as matrix inversion and determinant.
|
* This module includes %LU decomposition and related notions such as matrix inversion and determinant.
|
||||||
* This module defines the following MatrixBase methods:
|
* This module defines the following MatrixBase methods:
|
||||||
@@ -23,27 +18,25 @@
|
|||||||
* \endcode
|
* \endcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
#include "src/misc/Solve.h"
|
||||||
#include "src/misc/Kernel.h"
|
#include "src/misc/Kernel.h"
|
||||||
#include "src/misc/Image.h"
|
#include "src/misc/Image.h"
|
||||||
#include "src/misc/RankRevealingBase.h"
|
|
||||||
#include "src/LU/FullPivLU.h"
|
#include "src/LU/FullPivLU.h"
|
||||||
#include "src/LU/PartialPivLU.h"
|
#include "src/LU/PartialPivLU.h"
|
||||||
#ifdef EIGEN_USE_LAPACKE
|
|
||||||
#include "src/misc/lapacke_helpers.h"
|
|
||||||
#include "src/LU/PartialPivLU_LAPACKE.h"
|
|
||||||
#endif
|
|
||||||
#include "src/LU/Determinant.h"
|
#include "src/LU/Determinant.h"
|
||||||
#include "src/LU/InverseImpl.h"
|
#include "src/LU/Inverse.h"
|
||||||
|
|
||||||
#ifndef EIGEN_VECTORIZE_GENERIC
|
#if defined EIGEN_VECTORIZE_SSE
|
||||||
// TODO(rmlarsen): Make these work with generic vectorization if possible.
|
#include "src/LU/arch/Inverse_SSE.h"
|
||||||
#if defined EIGEN_VECTORIZE_SSE || defined EIGEN_VECTORIZE_NEON
|
|
||||||
#include "src/LU/arch/InverseSize4.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef EIGEN2_SUPPORT
|
||||||
|
#include "src/Eigen2Support/LU.h"
|
||||||
#endif
|
#endif
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
} // namespace Eigen
|
||||||
|
|
||||||
#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: */
|
||||||
|
|||||||
36
Eigen/LeastSquares
Normal file
36
Eigen/LeastSquares
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef EIGEN_REGRESSION_MODULE_H
|
||||||
|
#define EIGEN_REGRESSION_MODULE_H
|
||||||
|
|
||||||
|
#ifndef EIGEN2_SUPPORT
|
||||||
|
#error LeastSquares is only available in Eigen2 support mode (define EIGEN2_SUPPORT)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// exclude from normal eigen3-only documentation
|
||||||
|
#ifdef EIGEN2_SUPPORT
|
||||||
|
|
||||||
|
#include "Core"
|
||||||
|
|
||||||
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
|
#include "Eigenvalues"
|
||||||
|
#include "Geometry"
|
||||||
|
|
||||||
|
namespace Eigen {
|
||||||
|
|
||||||
|
/** \defgroup LeastSquares_Module LeastSquares module
|
||||||
|
* This module provides linear regression and related features.
|
||||||
|
*
|
||||||
|
* \code
|
||||||
|
* #include <Eigen/LeastSquares>
|
||||||
|
* \endcode
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "src/Eigen2Support/LeastSquares.h"
|
||||||
|
|
||||||
|
} // namespace Eigen
|
||||||
|
|
||||||
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
|
#endif // EIGEN2_SUPPORT
|
||||||
|
|
||||||
|
#endif // EIGEN_REGRESSION_MODULE_H
|
||||||
@@ -1,35 +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_METISSUPPORT_MODULE_H
|
|
||||||
#define EIGEN_METISSUPPORT_MODULE_H
|
|
||||||
|
|
||||||
#include "SparseCore"
|
|
||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include <metis.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \ingroup Support_modules
|
|
||||||
* \defgroup MetisSupport_Module MetisSupport module
|
|
||||||
*
|
|
||||||
* \code
|
|
||||||
* #include <Eigen/MetisSupport>
|
|
||||||
* \endcode
|
|
||||||
* This module defines an interface to the METIS reordering package (http://glaros.dtc.umn.edu/gkhome/views/metis).
|
|
||||||
* It can be used just as any other built-in method as explained in \link OrderingMethods_Module here. \endlink
|
|
||||||
*/
|
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/MetisSupport/MetisSupport.h"
|
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
|
||||||
|
|
||||||
#endif // EIGEN_METISSUPPORT_MODULE_H
|
|
||||||
@@ -1,73 +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_ORDERINGMETHODS_MODULE_H
|
|
||||||
#define EIGEN_ORDERINGMETHODS_MODULE_H
|
|
||||||
|
|
||||||
#include "SparseCore"
|
|
||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \defgroup OrderingMethods_Module OrderingMethods module
|
|
||||||
*
|
|
||||||
* This module is currently for internal use only
|
|
||||||
*
|
|
||||||
* It defines various built-in and external ordering methods for sparse matrices.
|
|
||||||
* They are typically used to reduce the number of elements during
|
|
||||||
* the sparse matrix decomposition (LLT, LU, QR).
|
|
||||||
* Precisely, in a preprocessing step, a permutation matrix P is computed using
|
|
||||||
* those ordering methods and applied to the columns of the matrix.
|
|
||||||
* Using for instance the sparse Cholesky decomposition, it is expected that
|
|
||||||
* the nonzeros elements in LLT(A*P) will be much smaller than that in LLT(A).
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Usage :
|
|
||||||
* \code
|
|
||||||
* #include <Eigen/OrderingMethods>
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* A simple usage is as a template parameter in the sparse decomposition classes :
|
|
||||||
*
|
|
||||||
* \code
|
|
||||||
* SparseLU<MatrixType, COLAMDOrdering<int> > solver;
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* \code
|
|
||||||
* SparseQR<MatrixType, COLAMDOrdering<int> > solver;
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* It is possible as well to call directly a particular ordering method for your own purpose,
|
|
||||||
* \code
|
|
||||||
* AMDOrdering<int> ordering;
|
|
||||||
* PermutationMatrix<Dynamic, Dynamic, int> perm;
|
|
||||||
* SparseMatrix<double> A;
|
|
||||||
* //Fill the matrix ...
|
|
||||||
*
|
|
||||||
* ordering(A, perm); // Call AMD
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* \note Some of these methods (like AMD or METIS), need the sparsity pattern
|
|
||||||
* of the input matrix to be symmetric. When the matrix is structurally unsymmetric,
|
|
||||||
* Eigen computes internally the pattern of \f$A^T*A\f$ before calling the method.
|
|
||||||
* If your matrix is already symmetric (at least in structure), you can avoid that
|
|
||||||
* by calling the method with a SelfAdjointView type.
|
|
||||||
*
|
|
||||||
* \code
|
|
||||||
* // Call the ordering on the pattern of the lower triangular matrix A
|
|
||||||
* ordering(A.selfadjointView<Lower>(), perm);
|
|
||||||
* \endcode
|
|
||||||
*/
|
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/OrderingMethods/Amd.h"
|
|
||||||
#include "src/OrderingMethods/Ordering.h"
|
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
|
||||||
|
|
||||||
#endif // EIGEN_ORDERINGMETHODS_MODULE_H
|
|
||||||
@@ -1,51 +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_PASTIXSUPPORT_MODULE_H
|
|
||||||
#define EIGEN_PASTIXSUPPORT_MODULE_H
|
|
||||||
|
|
||||||
#include "SparseCore"
|
|
||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include <pastix_nompi.h>
|
|
||||||
#include <pastix.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef complex
|
|
||||||
#undef complex
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \ingroup Support_modules
|
|
||||||
* \defgroup PaStiXSupport_Module PaStiXSupport module
|
|
||||||
*
|
|
||||||
* This module provides an interface to the <a href="http://pastix.gforge.inria.fr/">PaSTiX</a> library.
|
|
||||||
* PaSTiX is a general \b supernodal, \b parallel and \b opensource sparse solver.
|
|
||||||
* It provides the two following main factorization classes:
|
|
||||||
* - class PastixLLT : a supernodal, parallel LLt Cholesky factorization.
|
|
||||||
* - class PastixLDLT: a supernodal, parallel LDLt Cholesky factorization.
|
|
||||||
* - class PastixLU : a supernodal, parallel LU factorization (optimized for a symmetric pattern).
|
|
||||||
*
|
|
||||||
* \code
|
|
||||||
* #include <Eigen/PaStiXSupport>
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* In order to use this module, the PaSTiX headers must be accessible from the include paths, and your binary must be
|
|
||||||
* linked to the PaSTiX library and its dependencies. This wrapper requires PaStiX version 5.x compiled without MPI
|
|
||||||
* support. 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/PaStiXSupport/PaStiXSupport.h"
|
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
|
||||||
|
|
||||||
#endif // EIGEN_PASTIXSUPPORT_MODULE_H
|
|
||||||
@@ -1,38 +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_PARDISOSUPPORT_MODULE_H
|
|
||||||
#define EIGEN_PARDISOSUPPORT_MODULE_H
|
|
||||||
|
|
||||||
#include "SparseCore"
|
|
||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
|
||||||
|
|
||||||
#include <mkl_pardiso.h>
|
|
||||||
|
|
||||||
/** \ingroup Support_modules
|
|
||||||
* \defgroup PardisoSupport_Module PardisoSupport module
|
|
||||||
*
|
|
||||||
* This module brings support for the Intel(R) MKL PARDISO direct sparse solvers.
|
|
||||||
*
|
|
||||||
* \code
|
|
||||||
* #include <Eigen/PardisoSupport>
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* In order to use this module, the MKL headers must be accessible from the include paths, and your binary must be
|
|
||||||
* linked to the MKL library and its dependencies. See this \ref TopicUsingIntelMKL "page" for more information on
|
|
||||||
* MKL-Eigen integration.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/PardisoSupport/PardisoSupport.h"
|
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
|
||||||
|
|
||||||
#endif // EIGEN_PARDISOSUPPORT_MODULE_H
|
|
||||||
38
Eigen/QR
38
Eigen/QR
@@ -1,47 +1,45 @@
|
|||||||
// 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_QR_MODULE_H
|
#ifndef EIGEN_QR_MODULE_H
|
||||||
#define EIGEN_QR_MODULE_H
|
#define EIGEN_QR_MODULE_H
|
||||||
|
|
||||||
#include "Core"
|
#include "Core"
|
||||||
|
|
||||||
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
#include "Cholesky"
|
#include "Cholesky"
|
||||||
|
#include "Jacobi"
|
||||||
#include "Householder"
|
#include "Householder"
|
||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
namespace Eigen {
|
||||||
|
|
||||||
/** \defgroup QR_Module QR module
|
/** \defgroup QR_Module QR module
|
||||||
|
*
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* This module provides various QR decompositions
|
* This module provides various QR decompositions
|
||||||
* This module also provides some MatrixBase methods, including:
|
* This module also provides some MatrixBase methods, including:
|
||||||
* - MatrixBase::householderQr()
|
* - MatrixBase::qr(),
|
||||||
* - MatrixBase::colPivHouseholderQr()
|
|
||||||
* - MatrixBase::fullPivHouseholderQr()
|
|
||||||
*
|
*
|
||||||
* \code
|
* \code
|
||||||
* #include <Eigen/QR>
|
* #include <Eigen/QR>
|
||||||
* \endcode
|
* \endcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "src/misc/RankRevealingBase.h"
|
#include "src/misc/Solve.h"
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/QR/HouseholderQR.h"
|
#include "src/QR/HouseholderQR.h"
|
||||||
#include "src/QR/FullPivHouseholderQR.h"
|
#include "src/QR/FullPivHouseholderQR.h"
|
||||||
#include "src/QR/ColPivHouseholderQR.h"
|
#include "src/QR/ColPivHouseholderQR.h"
|
||||||
#include "src/QR/CompleteOrthogonalDecomposition.h"
|
|
||||||
#ifdef EIGEN_USE_LAPACKE
|
#ifdef EIGEN2_SUPPORT
|
||||||
#include "src/misc/lapacke_helpers.h"
|
#include "src/Eigen2Support/QR.h"
|
||||||
#include "src/QR/HouseholderQR_LAPACKE.h"
|
|
||||||
#include "src/QR/ColPivHouseholderQR_LAPACKE.h"
|
|
||||||
#endif
|
#endif
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
} // namespace Eigen
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
|
#ifdef EIGEN2_SUPPORT
|
||||||
|
#include "Eigenvalues"
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // EIGEN_QR_MODULE_H
|
#endif // EIGEN_QR_MODULE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
|||||||
@@ -1,9 +1,3 @@
|
|||||||
// 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_QTMALLOC_MODULE_H
|
#ifndef EIGEN_QTMALLOC_MODULE_H
|
||||||
#define EIGEN_QTMALLOC_MODULE_H
|
#define EIGEN_QTMALLOC_MODULE_H
|
||||||
@@ -14,13 +8,20 @@
|
|||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
inline void *qMalloc(std::size_t size) { return Eigen::internal::aligned_malloc(size); }
|
void *qMalloc(size_t size)
|
||||||
|
{
|
||||||
|
return Eigen::internal::aligned_malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
inline void qFree(void *ptr) { Eigen::internal::aligned_free(ptr); }
|
void qFree(void *ptr)
|
||||||
|
{
|
||||||
|
Eigen::internal::aligned_free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
inline void *qRealloc(void *ptr, std::size_t size) {
|
void *qRealloc(void *ptr, size_t size)
|
||||||
|
{
|
||||||
void* newPtr = Eigen::internal::aligned_malloc(size);
|
void* newPtr = Eigen::internal::aligned_malloc(size);
|
||||||
std::memcpy(newPtr, ptr, size);
|
memcpy(newPtr, ptr, size);
|
||||||
Eigen::internal::aligned_free(ptr);
|
Eigen::internal::aligned_free(ptr);
|
||||||
return newPtr;
|
return newPtr;
|
||||||
}
|
}
|
||||||
@@ -30,3 +31,4 @@ inline 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: */
|
||||||
|
|||||||
@@ -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_SPQRSUPPORT_MODULE_H
|
|
||||||
#define EIGEN_SPQRSUPPORT_MODULE_H
|
|
||||||
|
|
||||||
#include "SparseCore"
|
|
||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
|
||||||
|
|
||||||
#include "SuiteSparseQR.hpp"
|
|
||||||
|
|
||||||
/** \ingroup Support_modules
|
|
||||||
* \defgroup SPQRSupport_Module SuiteSparseQR module
|
|
||||||
*
|
|
||||||
* This module provides an interface to the SPQR library, which is part of the <a
|
|
||||||
* href="http://www.suitesparse.com">suitesparse</a> package.
|
|
||||||
*
|
|
||||||
* \code
|
|
||||||
* #include <Eigen/SPQRSupport>
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* In order to use this module, the SPQR headers must be accessible from the include paths, and your binary must be
|
|
||||||
* linked to the SPQR library and its dependencies (Cholmod, AMD, COLAMD,...). For a cmake based project, you can use
|
|
||||||
* our FindSPQR.cmake and FindCholmod.Cmake modules
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "CholmodSupport"
|
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/SPQRSupport/SuiteSparseQRSupport.h"
|
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
|
||||||
|
|
||||||
#endif // EIGEN_SPQRSUPPORT_MODULE_H
|
|
||||||
45
Eigen/SVD
45
Eigen/SVD
@@ -1,53 +1,38 @@
|
|||||||
// 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_SVD_MODULE_H
|
#ifndef EIGEN_SVD_MODULE_H
|
||||||
#define EIGEN_SVD_MODULE_H
|
#define EIGEN_SVD_MODULE_H
|
||||||
|
|
||||||
#include "QR"
|
#include "QR"
|
||||||
|
#include "Householder"
|
||||||
|
#include "Jacobi"
|
||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
|
namespace Eigen {
|
||||||
|
|
||||||
/** \defgroup SVD_Module SVD module
|
/** \defgroup SVD_Module SVD module
|
||||||
|
*
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* This module provides SVD decomposition for matrices (both real and complex).
|
* This module provides SVD decomposition for matrices (both real and complex).
|
||||||
* Two decomposition algorithms are provided:
|
* This decomposition is accessible via the following MatrixBase method:
|
||||||
* - JacobiSVD implementing two-sided Jacobi iterations is numerically very accurate, fast for small matrices, but very
|
|
||||||
* slow for larger ones.
|
|
||||||
* - BDCSVD implementing a recursive divide & conquer strategy on top of an upper-bidiagonalization which remains fast
|
|
||||||
* for large problems. These decompositions are accessible via the respective classes and following MatrixBase methods:
|
|
||||||
* - MatrixBase::jacobiSvd()
|
* - MatrixBase::jacobiSvd()
|
||||||
* - MatrixBase::bdcSvd()
|
|
||||||
*
|
*
|
||||||
* \code
|
* \code
|
||||||
* #include <Eigen/SVD>
|
* #include <Eigen/SVD>
|
||||||
* \endcode
|
* \endcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
#include "src/misc/Solve.h"
|
||||||
#include "src/SVD/UpperBidiagonalization.h"
|
|
||||||
#include "src/SVD/SVDBase.h"
|
|
||||||
#include "src/SVD/JacobiSVD.h"
|
#include "src/SVD/JacobiSVD.h"
|
||||||
#include "src/SVD/BDCSVD.h"
|
#include "src/SVD/UpperBidiagonalization.h"
|
||||||
#ifdef EIGEN_USE_LAPACKE
|
|
||||||
#ifdef EIGEN_USE_MKL
|
#ifdef EIGEN2_SUPPORT
|
||||||
#include "mkl_lapacke.h"
|
#include "src/Eigen2Support/SVD.h"
|
||||||
#elif defined(EIGEN_LAPACKE_SYSTEM)
|
|
||||||
#include <lapacke.h>
|
|
||||||
#else
|
|
||||||
#include "src/misc/lapacke.h"
|
|
||||||
#endif
|
#endif
|
||||||
#ifndef EIGEN_USE_LAPACKE_STRICT
|
|
||||||
#include "src/SVD/JacobiSVD_LAPACKE.h"
|
} // namespace Eigen
|
||||||
#endif
|
|
||||||
#include "src/SVD/BDCSVD_LAPACKE.h"
|
|
||||||
#endif
|
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#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: */
|
||||||
|
|||||||
84
Eigen/Sparse
84
Eigen/Sparse
@@ -1,33 +1,69 @@
|
|||||||
// 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_SPARSE_MODULE_H
|
#ifndef EIGEN_SPARSE_MODULE_H
|
||||||
#define EIGEN_SPARSE_MODULE_H
|
#define EIGEN_SPARSE_MODULE_H
|
||||||
|
|
||||||
/** \defgroup Sparse_Module Sparse meta-module
|
#include "Core"
|
||||||
|
|
||||||
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#ifdef EIGEN2_SUPPORT
|
||||||
|
#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
|
||||||
|
#error The sparse module API is not stable yet. To use it anyway, please define the EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET preprocessor token.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Eigen {
|
||||||
|
|
||||||
|
/** \defgroup Sparse_Module Sparse module
|
||||||
*
|
*
|
||||||
* Meta-module including all related modules:
|
|
||||||
* - \ref SparseCore_Module
|
|
||||||
* - \ref OrderingMethods_Module
|
|
||||||
* - \ref SparseCholesky_Module
|
|
||||||
* - \ref SparseLU_Module
|
|
||||||
* - \ref SparseQR_Module
|
|
||||||
* - \ref IterativeLinearSolvers_Module
|
|
||||||
*
|
*
|
||||||
\code
|
*
|
||||||
#include <Eigen/Sparse>
|
* See the \ref TutorialSparse "Sparse tutorial"
|
||||||
\endcode
|
*
|
||||||
|
* \code
|
||||||
|
* #include <Eigen/Sparse>
|
||||||
|
* \endcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "SparseCore"
|
/** The type used to identify a general sparse storage. */
|
||||||
#include "OrderingMethods"
|
struct Sparse {};
|
||||||
#include "SparseCholesky"
|
|
||||||
#include "SparseLU"
|
#include "src/Sparse/SparseUtil.h"
|
||||||
#include "SparseQR"
|
#include "src/Sparse/SparseMatrixBase.h"
|
||||||
#include "IterativeLinearSolvers"
|
#include "src/Sparse/CompressedStorage.h"
|
||||||
|
#include "src/Sparse/AmbiVector.h"
|
||||||
|
#include "src/Sparse/SparseMatrix.h"
|
||||||
|
#include "src/Sparse/DynamicSparseMatrix.h"
|
||||||
|
#include "src/Sparse/MappedSparseMatrix.h"
|
||||||
|
#include "src/Sparse/SparseVector.h"
|
||||||
|
#include "src/Sparse/CoreIterators.h"
|
||||||
|
#include "src/Sparse/SparseBlock.h"
|
||||||
|
#include "src/Sparse/SparseTranspose.h"
|
||||||
|
#include "src/Sparse/SparseCwiseUnaryOp.h"
|
||||||
|
#include "src/Sparse/SparseCwiseBinaryOp.h"
|
||||||
|
#include "src/Sparse/SparseDot.h"
|
||||||
|
#include "src/Sparse/SparseAssign.h"
|
||||||
|
#include "src/Sparse/SparseRedux.h"
|
||||||
|
#include "src/Sparse/SparseFuzzy.h"
|
||||||
|
#include "src/Sparse/SparseProduct.h"
|
||||||
|
#include "src/Sparse/SparseSparseProduct.h"
|
||||||
|
#include "src/Sparse/SparseDenseProduct.h"
|
||||||
|
#include "src/Sparse/SparseDiagonalProduct.h"
|
||||||
|
#include "src/Sparse/SparseTriangularView.h"
|
||||||
|
#include "src/Sparse/SparseSelfAdjointView.h"
|
||||||
|
#include "src/Sparse/TriangularSolver.h"
|
||||||
|
#include "src/Sparse/SparseView.h"
|
||||||
|
|
||||||
|
} // namespace Eigen
|
||||||
|
|
||||||
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_SPARSE_MODULE_H
|
#endif // EIGEN_SPARSE_MODULE_H
|
||||||
|
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008-2013 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_SPARSECHOLESKY_MODULE_H
|
|
||||||
#define EIGEN_SPARSECHOLESKY_MODULE_H
|
|
||||||
|
|
||||||
#include "SparseCore"
|
|
||||||
#include "OrderingMethods"
|
|
||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \defgroup SparseCholesky_Module SparseCholesky module
|
|
||||||
*
|
|
||||||
* This module currently provides two variants of the direct sparse Cholesky decomposition for selfadjoint (hermitian)
|
|
||||||
* matrices. Those decompositions are accessible via the following classes:
|
|
||||||
* - SimplicialLLt,
|
|
||||||
* - SimplicialLDLt
|
|
||||||
*
|
|
||||||
* Such problems can also be solved using the ConjugateGradient solver from the IterativeLinearSolvers module.
|
|
||||||
*
|
|
||||||
* \code
|
|
||||||
* #include <Eigen/SparseCholesky>
|
|
||||||
* \endcode
|
|
||||||
*/
|
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/SparseCholesky/SimplicialCholesky.h"
|
|
||||||
#include "src/SparseCholesky/SimplicialCholesky_impl.h"
|
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
|
||||||
|
|
||||||
#endif // EIGEN_SPARSECHOLESKY_MODULE_H
|
|
||||||
@@ -1,66 +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_SPARSECORE_MODULE_H
|
|
||||||
#define EIGEN_SPARSECORE_MODULE_H
|
|
||||||
|
|
||||||
#include "Core"
|
|
||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <numeric>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \defgroup SparseCore_Module SparseCore module
|
|
||||||
*
|
|
||||||
* This module provides a sparse matrix representation, and basic associated matrix manipulations
|
|
||||||
* and operations.
|
|
||||||
*
|
|
||||||
* See the \ref TutorialSparse "Sparse tutorial"
|
|
||||||
*
|
|
||||||
* \code
|
|
||||||
* #include <Eigen/SparseCore>
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* This module depends on: Core.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/SparseCore/SparseUtil.h"
|
|
||||||
#include "src/SparseCore/SparseMatrixBase.h"
|
|
||||||
#include "src/SparseCore/SparseAssign.h"
|
|
||||||
#include "src/SparseCore/CompressedStorage.h"
|
|
||||||
#include "src/SparseCore/AmbiVector.h"
|
|
||||||
#include "src/SparseCore/SparseCompressedBase.h"
|
|
||||||
#include "src/SparseCore/SparseMatrix.h"
|
|
||||||
#include "src/SparseCore/SparseMap.h"
|
|
||||||
#include "src/SparseCore/SparseVector.h"
|
|
||||||
#include "src/SparseCore/SparseRef.h"
|
|
||||||
#include "src/SparseCore/SparseCwiseUnaryOp.h"
|
|
||||||
#include "src/SparseCore/SparseCwiseBinaryOp.h"
|
|
||||||
#include "src/SparseCore/SparseTranspose.h"
|
|
||||||
#include "src/SparseCore/SparseBlock.h"
|
|
||||||
#include "src/SparseCore/SparseDot.h"
|
|
||||||
#include "src/SparseCore/SparseRedux.h"
|
|
||||||
#include "src/SparseCore/SparseView.h"
|
|
||||||
#include "src/SparseCore/SparseDiagonalProduct.h"
|
|
||||||
#include "src/SparseCore/ConservativeSparseSparseProduct.h"
|
|
||||||
#include "src/SparseCore/SparseSparseProductWithPruning.h"
|
|
||||||
#include "src/SparseCore/SparseProduct.h"
|
|
||||||
#include "src/SparseCore/SparseDenseProduct.h"
|
|
||||||
#include "src/SparseCore/SparseSelfAdjointView.h"
|
|
||||||
#include "src/SparseCore/SparseTriangularView.h"
|
|
||||||
#include "src/SparseCore/TriangularSolver.h"
|
|
||||||
#include "src/SparseCore/SparsePermutation.h"
|
|
||||||
#include "src/SparseCore/SparseFuzzy.h"
|
|
||||||
#include "src/SparseCore/SparseSolverBase.h"
|
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
|
||||||
|
|
||||||
#endif // EIGEN_SPARSECORE_MODULE_H
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
|
|
||||||
// Copyright (C) 2012 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_SPARSELU_MODULE_H
|
|
||||||
#define EIGEN_SPARSELU_MODULE_H
|
|
||||||
|
|
||||||
#include "SparseCore"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \defgroup SparseLU_Module SparseLU module
|
|
||||||
* This module defines a supernodal factorization of general sparse matrices.
|
|
||||||
* The code is fully optimized for supernode-panel updates with specialized kernels.
|
|
||||||
* Please, see the documentation of the SparseLU class for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Ordering interface
|
|
||||||
#include "OrderingMethods"
|
|
||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/SparseLU/SparseLU_Structs.h"
|
|
||||||
#include "src/SparseLU/SparseLU_SupernodalMatrix.h"
|
|
||||||
#include "src/SparseLU/SparseLUImpl.h"
|
|
||||||
#include "src/SparseCore/SparseColEtree.h"
|
|
||||||
#include "src/SparseLU/SparseLU_Memory.h"
|
|
||||||
#include "src/SparseLU/SparseLU_heap_relax_snode.h"
|
|
||||||
#include "src/SparseLU/SparseLU_relax_snode.h"
|
|
||||||
#include "src/SparseLU/SparseLU_pivotL.h"
|
|
||||||
#include "src/SparseLU/SparseLU_panel_dfs.h"
|
|
||||||
#include "src/SparseLU/SparseLU_kernel_bmod.h"
|
|
||||||
#include "src/SparseLU/SparseLU_panel_bmod.h"
|
|
||||||
#include "src/SparseLU/SparseLU_column_dfs.h"
|
|
||||||
#include "src/SparseLU/SparseLU_column_bmod.h"
|
|
||||||
#include "src/SparseLU/SparseLU_copy_to_ucol.h"
|
|
||||||
#include "src/SparseLU/SparseLU_pruneL.h"
|
|
||||||
#include "src/SparseLU/SparseLU_Utils.h"
|
|
||||||
#include "src/SparseLU/SparseLU.h"
|
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
|
||||||
|
|
||||||
#endif // EIGEN_SPARSELU_MODULE_H
|
|
||||||
@@ -1,38 +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_SPARSEQR_MODULE_H
|
|
||||||
#define EIGEN_SPARSEQR_MODULE_H
|
|
||||||
|
|
||||||
#include "SparseCore"
|
|
||||||
#include "OrderingMethods"
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
|
||||||
|
|
||||||
/** \defgroup SparseQR_Module SparseQR module
|
|
||||||
* \brief Provides QR decomposition for sparse matrices
|
|
||||||
*
|
|
||||||
* This module provides a simplicial version of the left-looking Sparse QR decomposition.
|
|
||||||
* The columns of the input matrix should be reordered to limit the fill-in during the
|
|
||||||
* decomposition. Built-in methods (COLAMD, AMD) or external methods (METIS) can be used to this end.
|
|
||||||
* See the \link OrderingMethods_Module OrderingMethods\endlink module for the list
|
|
||||||
* of built-in and external ordering methods.
|
|
||||||
*
|
|
||||||
* \code
|
|
||||||
* #include <Eigen/SparseQR>
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/SparseCore/SparseColEtree.h"
|
|
||||||
#include "src/SparseQR/SparseQR.h"
|
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
|
||||||
|
|
||||||
#endif // EIGEN_SPARSEQR_MODULE_H
|
|
||||||
@@ -4,9 +4,24 @@
|
|||||||
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
|
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_STDDEQUE_MODULE_H
|
#ifndef EIGEN_STDDEQUE_MODULE_H
|
||||||
#define EIGEN_STDDEQUE_MODULE_H
|
#define EIGEN_STDDEQUE_MODULE_H
|
||||||
@@ -14,16 +29,13 @@
|
|||||||
#include "Core"
|
#include "Core"
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
#if EIGEN_COMP_MSVC && EIGEN_OS_WIN64 && \
|
#if (defined(_MSC_VER) && defined(_WIN64)) /* MSVC auto aligns in 64 bit builds */
|
||||||
(EIGEN_MAX_STATIC_ALIGN_BYTES <= 16) /* MSVC auto aligns up to 16 bytes in 64 bit builds */
|
|
||||||
|
|
||||||
#define EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(...)
|
#define EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(...)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/StlSupport/StdDeque.h"
|
#include "src/StlSupport/StdDeque.h"
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,24 @@
|
|||||||
//
|
//
|
||||||
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
|
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_STDLIST_MODULE_H
|
#ifndef EIGEN_STDLIST_MODULE_H
|
||||||
#define EIGEN_STDLIST_MODULE_H
|
#define EIGEN_STDLIST_MODULE_H
|
||||||
@@ -13,16 +28,13 @@
|
|||||||
#include "Core"
|
#include "Core"
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#if EIGEN_COMP_MSVC && EIGEN_OS_WIN64 && \
|
#if (defined(_MSC_VER) && defined(_WIN64)) /* MSVC auto aligns in 64 bit builds */
|
||||||
(EIGEN_MAX_STATIC_ALIGN_BYTES <= 16) /* MSVC auto aligns up to 16 bytes in 64 bit builds */
|
|
||||||
|
|
||||||
#define EIGEN_DEFINE_STL_LIST_SPECIALIZATION(...)
|
#define EIGEN_DEFINE_STL_LIST_SPECIALIZATION(...)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/StlSupport/StdList.h"
|
#include "src/StlSupport/StdList.h"
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,24 @@
|
|||||||
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
|
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_STDVECTOR_MODULE_H
|
#ifndef EIGEN_STDVECTOR_MODULE_H
|
||||||
#define EIGEN_STDVECTOR_MODULE_H
|
#define EIGEN_STDVECTOR_MODULE_H
|
||||||
@@ -14,16 +29,13 @@
|
|||||||
#include "Core"
|
#include "Core"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#if EIGEN_COMP_MSVC && EIGEN_OS_WIN64 && \
|
#if (defined(_MSC_VER) && defined(_WIN64)) /* MSVC auto aligns in 64 bit builds */
|
||||||
(EIGEN_MAX_STATIC_ALIGN_BYTES <= 16) /* MSVC auto aligns up to 16 bytes in 64 bit builds */
|
|
||||||
|
|
||||||
#define EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(...)
|
#define EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(...)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/StlSupport/StdVector.h"
|
#include "src/StlSupport/StdVector.h"
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,71 +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_SUPERLUSUPPORT_MODULE_H
|
|
||||||
#define EIGEN_SUPERLUSUPPORT_MODULE_H
|
|
||||||
|
|
||||||
#include "SparseCore"
|
|
||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
|
||||||
|
|
||||||
#ifdef EMPTY
|
|
||||||
#define EIGEN_EMPTY_WAS_ALREADY_DEFINED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Required by SuperLU headers, which expect int_t to be defined as a global typedef.
|
|
||||||
typedef int int_t;
|
|
||||||
#include <slu_Cnames.h>
|
|
||||||
#include <supermatrix.h>
|
|
||||||
#include <slu_util.h>
|
|
||||||
|
|
||||||
// slu_util.h defines a preprocessor token named EMPTY which is really polluting,
|
|
||||||
// so we remove it in favor of a SUPERLU_EMPTY token.
|
|
||||||
// If EMPTY was already defined then we don't undef it.
|
|
||||||
|
|
||||||
#if defined(EIGEN_EMPTY_WAS_ALREADY_DEFINED)
|
|
||||||
#undef EIGEN_EMPTY_WAS_ALREADY_DEFINED
|
|
||||||
#elif defined(EMPTY)
|
|
||||||
#undef EMPTY
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SUPERLU_EMPTY (-1)
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
struct SluMatrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \ingroup Support_modules
|
|
||||||
* \defgroup SuperLUSupport_Module SuperLUSupport module
|
|
||||||
*
|
|
||||||
* This module provides an interface to the <a href="http://crd-legacy.lbl.gov/~xiaoye/SuperLU/">SuperLU</a> library.
|
|
||||||
* It provides the following factorization class:
|
|
||||||
* - class SuperLU: a supernodal sequential LU factorization.
|
|
||||||
* - class SuperILU: a supernodal sequential incomplete LU factorization (to be used as a preconditioner for iterative
|
|
||||||
* methods).
|
|
||||||
*
|
|
||||||
* \warning This wrapper requires at least versions 4.0 of SuperLU. The 3.x versions are not supported.
|
|
||||||
*
|
|
||||||
* \warning When including this module, you have to use SUPERLU_EMPTY instead of EMPTY which is no longer defined
|
|
||||||
* because it is too polluting.
|
|
||||||
*
|
|
||||||
* \code
|
|
||||||
* #include <Eigen/SuperLUSupport>
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* In order to use this module, the superlu headers must be accessible from the include paths, and your binary must be
|
|
||||||
* linked to the superlu library and its dependencies. The dependencies depend on how superlu has been compiled. For a
|
|
||||||
* cmake based project, you can use our FindSuperLU.cmake module to help you in this task.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/SuperLUSupport/SuperLUSupport.h"
|
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
|
||||||
|
|
||||||
#endif // EIGEN_SUPERLUSUPPORT_MODULE_H
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2016 Benoit Steiner <benoit.steiner.goog@gmail.com>
|
|
||||||
//
|
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
#ifndef EIGEN_THREADPOOL_MODULE_H
|
|
||||||
#define EIGEN_THREADPOOL_MODULE_H
|
|
||||||
|
|
||||||
#include "Core"
|
|
||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
|
||||||
|
|
||||||
/** \defgroup ThreadPool_Module ThreadPool Module
|
|
||||||
*
|
|
||||||
* This module provides 2 threadpool implementations
|
|
||||||
* - a simple reference implementation
|
|
||||||
* - a faster non blocking implementation
|
|
||||||
*
|
|
||||||
* \code
|
|
||||||
* #include <Eigen/ThreadPool>
|
|
||||||
* \endcode
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cstring>
|
|
||||||
#include <ctime>
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <atomic>
|
|
||||||
#include <condition_variable>
|
|
||||||
#include <deque>
|
|
||||||
#include <mutex>
|
|
||||||
#include <thread>
|
|
||||||
#include <functional>
|
|
||||||
#include <memory>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
// There are non-parenthesized calls to "max" in the <unordered_map> header,
|
|
||||||
// which trigger a check in test/main.h causing compilation to fail.
|
|
||||||
// We work around the check here by removing the check for max in
|
|
||||||
// the case where we have to emulate thread_local.
|
|
||||||
#ifdef max
|
|
||||||
#undef max
|
|
||||||
#endif
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
#include "src/Core/util/Meta.h"
|
|
||||||
#include "src/Core/util/MaxSizeVector.h"
|
|
||||||
|
|
||||||
#ifndef EIGEN_MUTEX
|
|
||||||
#define EIGEN_MUTEX std::mutex
|
|
||||||
#endif
|
|
||||||
#ifndef EIGEN_MUTEX_LOCK
|
|
||||||
#define EIGEN_MUTEX_LOCK std::unique_lock<std::mutex>
|
|
||||||
#endif
|
|
||||||
#ifndef EIGEN_CONDVAR
|
|
||||||
#define EIGEN_CONDVAR std::condition_variable
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/ThreadPool/ThreadLocal.h"
|
|
||||||
#include "src/ThreadPool/ThreadYield.h"
|
|
||||||
#include "src/ThreadPool/ThreadCancel.h"
|
|
||||||
#include "src/ThreadPool/EventCount.h"
|
|
||||||
#include "src/ThreadPool/RunQueue.h"
|
|
||||||
#include "src/ThreadPool/ThreadPoolInterface.h"
|
|
||||||
#include "src/ThreadPool/ThreadEnvironment.h"
|
|
||||||
#include "src/ThreadPool/Barrier.h"
|
|
||||||
#include "src/ThreadPool/NonBlockingThreadPool.h"
|
|
||||||
#include "src/ThreadPool/CoreThreadPoolDevice.h"
|
|
||||||
#include "src/ThreadPool/ForkJoin.h"
|
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
|
||||||
|
|
||||||
#endif // EIGEN_THREADPOOL_MODULE_H
|
|
||||||
@@ -1,42 +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_UMFPACKSUPPORT_MODULE_H
|
|
||||||
#define EIGEN_UMFPACKSUPPORT_MODULE_H
|
|
||||||
|
|
||||||
#include "SparseCore"
|
|
||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include <umfpack.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \ingroup Support_modules
|
|
||||||
* \defgroup UmfPackSupport_Module UmfPackSupport module
|
|
||||||
*
|
|
||||||
* This module provides an interface to the UmfPack library which is part of the <a
|
|
||||||
* href="http://www.suitesparse.com">suitesparse</a> package. It provides the following factorization class:
|
|
||||||
* - class UmfPackLU: a multifrontal sequential LU factorization.
|
|
||||||
*
|
|
||||||
* \code
|
|
||||||
* #include <Eigen/UmfPackSupport>
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* In order to use this module, the umfpack headers must be accessible from the include paths, and your binary must be
|
|
||||||
* linked to the umfpack library and its dependencies. The dependencies depend on how umfpack has been compiled. For a
|
|
||||||
* cmake based project, you can use our FindUmfPack.cmake module to help you in this task.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// IWYU pragma: begin_exports
|
|
||||||
#include "src/UmfPackSupport/UmfPackSupport.h"
|
|
||||||
// IWYU pragma: end_exports
|
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
|
||||||
|
|
||||||
#endif // EIGEN_UMFPACKSUPPORT_MODULE_H
|
|
||||||
@@ -1,21 +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_VERSION_H
|
|
||||||
#define EIGEN_VERSION_H
|
|
||||||
|
|
||||||
// The "WORLD" version will forever remain "3" for the "Eigen3" library.
|
|
||||||
#define EIGEN_WORLD_VERSION 3
|
|
||||||
// As of Eigen3 5.0.0, we have moved to Semantic Versioning (semver.org).
|
|
||||||
#define EIGEN_MAJOR_VERSION 5
|
|
||||||
#define EIGEN_MINOR_VERSION 0
|
|
||||||
#define EIGEN_PATCH_VERSION 1
|
|
||||||
#define EIGEN_PRERELEASE_VERSION "dev"
|
|
||||||
#define EIGEN_BUILD_VERSION "master"
|
|
||||||
#define EIGEN_VERSION_STRING "5.0.1-dev+master"
|
|
||||||
|
|
||||||
#endif // EIGEN_VERSION_H
|
|
||||||
@@ -1,423 +0,0 @@
|
|||||||
#ifndef EIGEN_ACCELERATESUPPORT_H
|
|
||||||
#define EIGEN_ACCELERATESUPPORT_H
|
|
||||||
|
|
||||||
#include <Accelerate/Accelerate.h>
|
|
||||||
|
|
||||||
#include <Eigen/Sparse>
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
template <typename MatrixType_, int UpLo_, SparseFactorization_t Solver_, bool EnforceSquare_>
|
|
||||||
class AccelerateImpl;
|
|
||||||
|
|
||||||
/** \ingroup AccelerateSupport_Module
|
|
||||||
* \typedef AccelerateLLT
|
|
||||||
* \brief A direct Cholesky (LLT) factorization and solver based on Accelerate
|
|
||||||
*
|
|
||||||
* \warning Only single and double precision real scalar types are supported by Accelerate
|
|
||||||
*
|
|
||||||
* \tparam MatrixType_ the type of the sparse matrix A, it must be a SparseMatrix<>
|
|
||||||
* \tparam UpLo_ additional information about the matrix structure. Default is Lower.
|
|
||||||
*
|
|
||||||
* \sa \ref TutorialSparseSolverConcept, class AccelerateLLT
|
|
||||||
*/
|
|
||||||
template <typename MatrixType, int UpLo = Lower>
|
|
||||||
using AccelerateLLT = AccelerateImpl<MatrixType, UpLo | Symmetric, SparseFactorizationCholesky, true>;
|
|
||||||
|
|
||||||
/** \ingroup AccelerateSupport_Module
|
|
||||||
* \typedef AccelerateLDLT
|
|
||||||
* \brief The default Cholesky (LDLT) factorization and solver based on Accelerate
|
|
||||||
*
|
|
||||||
* \warning Only single and double precision real scalar types are supported by Accelerate
|
|
||||||
*
|
|
||||||
* \tparam MatrixType_ the type of the sparse matrix A, it must be a SparseMatrix<>
|
|
||||||
* \tparam UpLo_ additional information about the matrix structure. Default is Lower.
|
|
||||||
*
|
|
||||||
* \sa \ref TutorialSparseSolverConcept, class AccelerateLDLT
|
|
||||||
*/
|
|
||||||
template <typename MatrixType, int UpLo = Lower>
|
|
||||||
using AccelerateLDLT = AccelerateImpl<MatrixType, UpLo | Symmetric, SparseFactorizationLDLT, true>;
|
|
||||||
|
|
||||||
/** \ingroup AccelerateSupport_Module
|
|
||||||
* \typedef AccelerateLDLTUnpivoted
|
|
||||||
* \brief A direct Cholesky-like LDL^T factorization and solver based on Accelerate with only 1x1 pivots and no pivoting
|
|
||||||
*
|
|
||||||
* \warning Only single and double precision real scalar types are supported by Accelerate
|
|
||||||
*
|
|
||||||
* \tparam MatrixType_ the type of the sparse matrix A, it must be a SparseMatrix<>
|
|
||||||
* \tparam UpLo_ additional information about the matrix structure. Default is Lower.
|
|
||||||
*
|
|
||||||
* \sa \ref TutorialSparseSolverConcept, class AccelerateLDLTUnpivoted
|
|
||||||
*/
|
|
||||||
template <typename MatrixType, int UpLo = Lower>
|
|
||||||
using AccelerateLDLTUnpivoted = AccelerateImpl<MatrixType, UpLo | Symmetric, SparseFactorizationLDLTUnpivoted, true>;
|
|
||||||
|
|
||||||
/** \ingroup AccelerateSupport_Module
|
|
||||||
* \typedef AccelerateLDLTSBK
|
|
||||||
* \brief A direct Cholesky (LDLT) factorization and solver based on Accelerate with Supernode Bunch-Kaufman and static
|
|
||||||
* pivoting
|
|
||||||
*
|
|
||||||
* \warning Only single and double precision real scalar types are supported by Accelerate
|
|
||||||
*
|
|
||||||
* \tparam MatrixType_ the type of the sparse matrix A, it must be a SparseMatrix<>
|
|
||||||
* \tparam UpLo_ additional information about the matrix structure. Default is Lower.
|
|
||||||
*
|
|
||||||
* \sa \ref TutorialSparseSolverConcept, class AccelerateLDLTSBK
|
|
||||||
*/
|
|
||||||
template <typename MatrixType, int UpLo = Lower>
|
|
||||||
using AccelerateLDLTSBK = AccelerateImpl<MatrixType, UpLo | Symmetric, SparseFactorizationLDLTSBK, true>;
|
|
||||||
|
|
||||||
/** \ingroup AccelerateSupport_Module
|
|
||||||
* \typedef AccelerateLDLTTPP
|
|
||||||
* \brief A direct Cholesky (LDLT) factorization and solver based on Accelerate with full threshold partial pivoting
|
|
||||||
*
|
|
||||||
* \warning Only single and double precision real scalar types are supported by Accelerate
|
|
||||||
*
|
|
||||||
* \tparam MatrixType_ the type of the sparse matrix A, it must be a SparseMatrix<>
|
|
||||||
* \tparam UpLo_ additional information about the matrix structure. Default is Lower.
|
|
||||||
*
|
|
||||||
* \sa \ref TutorialSparseSolverConcept, class AccelerateLDLTTPP
|
|
||||||
*/
|
|
||||||
template <typename MatrixType, int UpLo = Lower>
|
|
||||||
using AccelerateLDLTTPP = AccelerateImpl<MatrixType, UpLo | Symmetric, SparseFactorizationLDLTTPP, true>;
|
|
||||||
|
|
||||||
/** \ingroup AccelerateSupport_Module
|
|
||||||
* \typedef AccelerateQR
|
|
||||||
* \brief A QR factorization and solver based on Accelerate
|
|
||||||
*
|
|
||||||
* \warning Only single and double precision real scalar types are supported by Accelerate
|
|
||||||
*
|
|
||||||
* \tparam MatrixType_ the type of the sparse matrix A, it must be a SparseMatrix<>
|
|
||||||
*
|
|
||||||
* \sa \ref TutorialSparseSolverConcept, class AccelerateQR
|
|
||||||
*/
|
|
||||||
template <typename MatrixType>
|
|
||||||
using AccelerateQR = AccelerateImpl<MatrixType, 0, SparseFactorizationQR, false>;
|
|
||||||
|
|
||||||
/** \ingroup AccelerateSupport_Module
|
|
||||||
* \typedef AccelerateCholeskyAtA
|
|
||||||
* \brief A QR factorization and solver based on Accelerate without storing Q (equivalent to A^TA = R^T R)
|
|
||||||
*
|
|
||||||
* \warning Only single and double precision real scalar types are supported by Accelerate
|
|
||||||
*
|
|
||||||
* \tparam MatrixType_ the type of the sparse matrix A, it must be a SparseMatrix<>
|
|
||||||
*
|
|
||||||
* \sa \ref TutorialSparseSolverConcept, class AccelerateCholeskyAtA
|
|
||||||
*/
|
|
||||||
template <typename MatrixType>
|
|
||||||
using AccelerateCholeskyAtA = AccelerateImpl<MatrixType, 0, SparseFactorizationCholeskyAtA, false>;
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
template <typename T>
|
|
||||||
struct AccelFactorizationDeleter {
|
|
||||||
void operator()(T* sym) const {
|
|
||||||
if (sym) {
|
|
||||||
SparseCleanup(*sym);
|
|
||||||
delete sym;
|
|
||||||
sym = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename DenseVecT, typename DenseMatT, typename SparseMatT, typename NumFactT>
|
|
||||||
struct SparseTypesTraitBase {
|
|
||||||
typedef DenseVecT AccelDenseVector;
|
|
||||||
typedef DenseMatT AccelDenseMatrix;
|
|
||||||
typedef SparseMatT AccelSparseMatrix;
|
|
||||||
|
|
||||||
typedef SparseOpaqueSymbolicFactorization SymbolicFactorization;
|
|
||||||
typedef NumFactT NumericFactorization;
|
|
||||||
|
|
||||||
typedef AccelFactorizationDeleter<SymbolicFactorization> SymbolicFactorizationDeleter;
|
|
||||||
typedef AccelFactorizationDeleter<NumericFactorization> NumericFactorizationDeleter;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Scalar>
|
|
||||||
struct SparseTypesTrait {};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct SparseTypesTrait<double> : SparseTypesTraitBase<DenseVector_Double, DenseMatrix_Double, SparseMatrix_Double,
|
|
||||||
SparseOpaqueFactorization_Double> {};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct SparseTypesTrait<float>
|
|
||||||
: SparseTypesTraitBase<DenseVector_Float, DenseMatrix_Float, SparseMatrix_Float, SparseOpaqueFactorization_Float> {
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
|
|
||||||
template <typename MatrixType_, int UpLo_, SparseFactorization_t Solver_, bool EnforceSquare_>
|
|
||||||
class AccelerateImpl : public SparseSolverBase<AccelerateImpl<MatrixType_, UpLo_, Solver_, EnforceSquare_> > {
|
|
||||||
protected:
|
|
||||||
using Base = SparseSolverBase<AccelerateImpl>;
|
|
||||||
using Base::derived;
|
|
||||||
using Base::m_isInitialized;
|
|
||||||
|
|
||||||
public:
|
|
||||||
using Base::_solve_impl;
|
|
||||||
|
|
||||||
typedef MatrixType_ MatrixType;
|
|
||||||
typedef typename MatrixType::Scalar Scalar;
|
|
||||||
typedef typename MatrixType::StorageIndex StorageIndex;
|
|
||||||
enum { ColsAtCompileTime = Dynamic, MaxColsAtCompileTime = Dynamic };
|
|
||||||
enum { UpLo = UpLo_ };
|
|
||||||
|
|
||||||
using AccelDenseVector = typename internal::SparseTypesTrait<Scalar>::AccelDenseVector;
|
|
||||||
using AccelDenseMatrix = typename internal::SparseTypesTrait<Scalar>::AccelDenseMatrix;
|
|
||||||
using AccelSparseMatrix = typename internal::SparseTypesTrait<Scalar>::AccelSparseMatrix;
|
|
||||||
using SymbolicFactorization = typename internal::SparseTypesTrait<Scalar>::SymbolicFactorization;
|
|
||||||
using NumericFactorization = typename internal::SparseTypesTrait<Scalar>::NumericFactorization;
|
|
||||||
using SymbolicFactorizationDeleter = typename internal::SparseTypesTrait<Scalar>::SymbolicFactorizationDeleter;
|
|
||||||
using NumericFactorizationDeleter = typename internal::SparseTypesTrait<Scalar>::NumericFactorizationDeleter;
|
|
||||||
|
|
||||||
AccelerateImpl() {
|
|
||||||
m_isInitialized = false;
|
|
||||||
|
|
||||||
auto check_flag_set = [](int value, int flag) { return ((value & flag) == flag); };
|
|
||||||
|
|
||||||
if (check_flag_set(UpLo_, Symmetric)) {
|
|
||||||
m_sparseKind = SparseSymmetric;
|
|
||||||
m_triType = (UpLo_ & Lower) ? SparseLowerTriangle : SparseUpperTriangle;
|
|
||||||
} else if (check_flag_set(UpLo_, UnitLower)) {
|
|
||||||
m_sparseKind = SparseUnitTriangular;
|
|
||||||
m_triType = SparseLowerTriangle;
|
|
||||||
} else if (check_flag_set(UpLo_, UnitUpper)) {
|
|
||||||
m_sparseKind = SparseUnitTriangular;
|
|
||||||
m_triType = SparseUpperTriangle;
|
|
||||||
} else if (check_flag_set(UpLo_, StrictlyLower)) {
|
|
||||||
m_sparseKind = SparseTriangular;
|
|
||||||
m_triType = SparseLowerTriangle;
|
|
||||||
} else if (check_flag_set(UpLo_, StrictlyUpper)) {
|
|
||||||
m_sparseKind = SparseTriangular;
|
|
||||||
m_triType = SparseUpperTriangle;
|
|
||||||
} else if (check_flag_set(UpLo_, Lower)) {
|
|
||||||
m_sparseKind = SparseTriangular;
|
|
||||||
m_triType = SparseLowerTriangle;
|
|
||||||
} else if (check_flag_set(UpLo_, Upper)) {
|
|
||||||
m_sparseKind = SparseTriangular;
|
|
||||||
m_triType = SparseUpperTriangle;
|
|
||||||
} else {
|
|
||||||
m_sparseKind = SparseOrdinary;
|
|
||||||
m_triType = (UpLo_ & Lower) ? SparseLowerTriangle : SparseUpperTriangle;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_order = SparseOrderDefault;
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit AccelerateImpl(const MatrixType& matrix) : AccelerateImpl() { compute(matrix); }
|
|
||||||
|
|
||||||
~AccelerateImpl() {}
|
|
||||||
|
|
||||||
inline Index cols() const { return m_nCols; }
|
|
||||||
inline Index rows() const { return m_nRows; }
|
|
||||||
|
|
||||||
ComputationInfo info() const {
|
|
||||||
eigen_assert(m_isInitialized && "Decomposition is not initialized.");
|
|
||||||
return m_info;
|
|
||||||
}
|
|
||||||
|
|
||||||
void analyzePattern(const MatrixType& matrix);
|
|
||||||
|
|
||||||
void factorize(const MatrixType& matrix);
|
|
||||||
|
|
||||||
void compute(const MatrixType& matrix);
|
|
||||||
|
|
||||||
template <typename Rhs, typename Dest>
|
|
||||||
void _solve_impl(const MatrixBase<Rhs>& b, MatrixBase<Dest>& dest) const;
|
|
||||||
|
|
||||||
/** Sets the ordering algorithm to use. */
|
|
||||||
void setOrder(SparseOrder_t order) { m_order = order; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
template <typename T>
|
|
||||||
void buildAccelSparseMatrix(const SparseMatrix<T>& a, AccelSparseMatrix& A, std::vector<long>& columnStarts) {
|
|
||||||
const Index nColumnsStarts = a.cols() + 1;
|
|
||||||
|
|
||||||
columnStarts.resize(nColumnsStarts);
|
|
||||||
|
|
||||||
for (Index i = 0; i < nColumnsStarts; i++) columnStarts[i] = a.outerIndexPtr()[i];
|
|
||||||
|
|
||||||
SparseAttributes_t attributes{};
|
|
||||||
attributes.transpose = false;
|
|
||||||
attributes.triangle = m_triType;
|
|
||||||
attributes.kind = m_sparseKind;
|
|
||||||
|
|
||||||
SparseMatrixStructure structure{};
|
|
||||||
structure.attributes = attributes;
|
|
||||||
structure.rowCount = static_cast<int>(a.rows());
|
|
||||||
structure.columnCount = static_cast<int>(a.cols());
|
|
||||||
structure.blockSize = 1;
|
|
||||||
structure.columnStarts = columnStarts.data();
|
|
||||||
structure.rowIndices = const_cast<int*>(a.innerIndexPtr());
|
|
||||||
|
|
||||||
A.structure = structure;
|
|
||||||
A.data = const_cast<T*>(a.valuePtr());
|
|
||||||
}
|
|
||||||
|
|
||||||
void doAnalysis(AccelSparseMatrix& A) {
|
|
||||||
m_numericFactorization.reset(nullptr);
|
|
||||||
|
|
||||||
SparseSymbolicFactorOptions opts{};
|
|
||||||
opts.control = SparseDefaultControl;
|
|
||||||
opts.orderMethod = m_order;
|
|
||||||
opts.order = nullptr;
|
|
||||||
opts.ignoreRowsAndColumns = nullptr;
|
|
||||||
opts.malloc = malloc;
|
|
||||||
opts.free = free;
|
|
||||||
opts.reportError = nullptr;
|
|
||||||
|
|
||||||
m_symbolicFactorization.reset(new SymbolicFactorization(SparseFactor(Solver_, A.structure, opts)));
|
|
||||||
|
|
||||||
SparseStatus_t status = m_symbolicFactorization->status;
|
|
||||||
|
|
||||||
updateInfoStatus(status);
|
|
||||||
|
|
||||||
if (status != SparseStatusOK) m_symbolicFactorization.reset(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void doFactorization(AccelSparseMatrix& A) {
|
|
||||||
SparseStatus_t status = SparseStatusReleased;
|
|
||||||
|
|
||||||
if (m_symbolicFactorization) {
|
|
||||||
m_numericFactorization.reset(new NumericFactorization(SparseFactor(*m_symbolicFactorization, A)));
|
|
||||||
|
|
||||||
status = m_numericFactorization->status;
|
|
||||||
|
|
||||||
if (status != SparseStatusOK) m_numericFactorization.reset(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateInfoStatus(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void updateInfoStatus(SparseStatus_t status) const {
|
|
||||||
switch (status) {
|
|
||||||
case SparseStatusOK:
|
|
||||||
m_info = Success;
|
|
||||||
break;
|
|
||||||
case SparseFactorizationFailed:
|
|
||||||
case SparseMatrixIsSingular:
|
|
||||||
m_info = NumericalIssue;
|
|
||||||
break;
|
|
||||||
case SparseInternalError:
|
|
||||||
case SparseParameterError:
|
|
||||||
case SparseStatusReleased:
|
|
||||||
default:
|
|
||||||
m_info = InvalidInput;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mutable ComputationInfo m_info;
|
|
||||||
Index m_nRows, m_nCols;
|
|
||||||
std::unique_ptr<SymbolicFactorization, SymbolicFactorizationDeleter> m_symbolicFactorization;
|
|
||||||
std::unique_ptr<NumericFactorization, NumericFactorizationDeleter> m_numericFactorization;
|
|
||||||
SparseKind_t m_sparseKind;
|
|
||||||
SparseTriangle_t m_triType;
|
|
||||||
SparseOrder_t m_order;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Computes the symbolic and numeric decomposition of matrix \a a */
|
|
||||||
template <typename MatrixType_, int UpLo_, SparseFactorization_t Solver_, bool EnforceSquare_>
|
|
||||||
void AccelerateImpl<MatrixType_, UpLo_, Solver_, EnforceSquare_>::compute(const MatrixType& a) {
|
|
||||||
if (EnforceSquare_) eigen_assert(a.rows() == a.cols());
|
|
||||||
|
|
||||||
m_nRows = a.rows();
|
|
||||||
m_nCols = a.cols();
|
|
||||||
|
|
||||||
AccelSparseMatrix A{};
|
|
||||||
std::vector<long> columnStarts;
|
|
||||||
|
|
||||||
buildAccelSparseMatrix(a, A, columnStarts);
|
|
||||||
|
|
||||||
doAnalysis(A);
|
|
||||||
|
|
||||||
if (m_symbolicFactorization) doFactorization(A);
|
|
||||||
|
|
||||||
m_isInitialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Performs a symbolic decomposition on the sparsity pattern of matrix \a a.
|
|
||||||
*
|
|
||||||
* This function is particularly useful when solving for several problems having the same structure.
|
|
||||||
*
|
|
||||||
* \sa factorize()
|
|
||||||
*/
|
|
||||||
template <typename MatrixType_, int UpLo_, SparseFactorization_t Solver_, bool EnforceSquare_>
|
|
||||||
void AccelerateImpl<MatrixType_, UpLo_, Solver_, EnforceSquare_>::analyzePattern(const MatrixType& a) {
|
|
||||||
if (EnforceSquare_) eigen_assert(a.rows() == a.cols());
|
|
||||||
|
|
||||||
m_nRows = a.rows();
|
|
||||||
m_nCols = a.cols();
|
|
||||||
|
|
||||||
AccelSparseMatrix A{};
|
|
||||||
std::vector<long> columnStarts;
|
|
||||||
|
|
||||||
buildAccelSparseMatrix(a, A, columnStarts);
|
|
||||||
|
|
||||||
doAnalysis(A);
|
|
||||||
|
|
||||||
m_isInitialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Performs a numeric decomposition of matrix \a a.
|
|
||||||
*
|
|
||||||
* The given matrix must have the same sparsity pattern as the matrix on which the symbolic decomposition has been
|
|
||||||
* performed.
|
|
||||||
*
|
|
||||||
* \sa analyzePattern()
|
|
||||||
*/
|
|
||||||
template <typename MatrixType_, int UpLo_, SparseFactorization_t Solver_, bool EnforceSquare_>
|
|
||||||
void AccelerateImpl<MatrixType_, UpLo_, Solver_, EnforceSquare_>::factorize(const MatrixType& a) {
|
|
||||||
eigen_assert(m_symbolicFactorization && "You must first call analyzePattern()");
|
|
||||||
eigen_assert(m_nRows == a.rows() && m_nCols == a.cols());
|
|
||||||
|
|
||||||
if (EnforceSquare_) eigen_assert(a.rows() == a.cols());
|
|
||||||
|
|
||||||
AccelSparseMatrix A{};
|
|
||||||
std::vector<long> columnStarts;
|
|
||||||
|
|
||||||
buildAccelSparseMatrix(a, A, columnStarts);
|
|
||||||
|
|
||||||
doFactorization(A);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename MatrixType_, int UpLo_, SparseFactorization_t Solver_, bool EnforceSquare_>
|
|
||||||
template <typename Rhs, typename Dest>
|
|
||||||
void AccelerateImpl<MatrixType_, UpLo_, Solver_, EnforceSquare_>::_solve_impl(const MatrixBase<Rhs>& b,
|
|
||||||
MatrixBase<Dest>& x) const {
|
|
||||||
if (!m_numericFactorization) {
|
|
||||||
m_info = InvalidInput;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
eigen_assert(m_nRows == b.rows());
|
|
||||||
eigen_assert(((b.cols() == 1) || b.outerStride() == b.rows()));
|
|
||||||
|
|
||||||
SparseStatus_t status = SparseStatusOK;
|
|
||||||
|
|
||||||
Scalar* b_ptr = const_cast<Scalar*>(b.derived().data());
|
|
||||||
Scalar* x_ptr = const_cast<Scalar*>(x.derived().data());
|
|
||||||
|
|
||||||
AccelDenseMatrix xmat{};
|
|
||||||
xmat.attributes = SparseAttributes_t();
|
|
||||||
xmat.columnCount = static_cast<int>(x.cols());
|
|
||||||
xmat.rowCount = static_cast<int>(x.rows());
|
|
||||||
xmat.columnStride = xmat.rowCount;
|
|
||||||
xmat.data = x_ptr;
|
|
||||||
|
|
||||||
AccelDenseMatrix bmat{};
|
|
||||||
bmat.attributes = SparseAttributes_t();
|
|
||||||
bmat.columnCount = static_cast<int>(b.cols());
|
|
||||||
bmat.rowCount = static_cast<int>(b.rows());
|
|
||||||
bmat.columnStride = bmat.rowCount;
|
|
||||||
bmat.data = b_ptr;
|
|
||||||
|
|
||||||
SparseSolve(*m_numericFactorization, bmat, xmat);
|
|
||||||
|
|
||||||
updateInfoStatus(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_ACCELERATESUPPORT_H
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
#ifndef EIGEN_ACCELERATESUPPORT_MODULE_H
|
|
||||||
#error "Please include Eigen/AccelerateSupport instead of including headers inside the src directory directly."
|
|
||||||
#endif
|
|
||||||
7
Eigen/src/CMakeLists.txt
Normal file
7
Eigen/src/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
file(GLOB Eigen_src_subdirectories "*")
|
||||||
|
escape_string_as_regex(ESCAPED_CMAKE_CURRENT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
|
foreach(f ${Eigen_src_subdirectories})
|
||||||
|
if(NOT f MATCHES "\\.txt" AND NOT f MATCHES "${ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/[.].+" )
|
||||||
|
add_subdirectory(${f})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
6
Eigen/src/Cholesky/CMakeLists.txt
Normal file
6
Eigen/src/Cholesky/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
FILE(GLOB Eigen_Cholesky_SRCS "*.h")
|
||||||
|
|
||||||
|
INSTALL(FILES
|
||||||
|
${Eigen_Cholesky_SRCS}
|
||||||
|
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Cholesky COMPONENT Devel
|
||||||
|
)
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
#ifndef EIGEN_CHOLESKY_MODULE_H
|
|
||||||
#error "Please include Eigen/Cholesky instead of including headers inside the src directory directly."
|
|
||||||
#endif
|
|
||||||
@@ -1,78 +1,77 @@
|
|||||||
// 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-2011 Gael Guennebaud <gael.guennebaud@inria.fr>
|
// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
// Copyright (C) 2009 Keir Mierle <mierle@gmail.com>
|
// Copyright (C) 2009 Keir Mierle <mierle@gmail.com>
|
||||||
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
|
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||||
// Copyright (C) 2011 Timothy E. Holy <tim.holy@gmail.com >
|
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_LDLT_H
|
#ifndef EIGEN_LDLT_H
|
||||||
#define EIGEN_LDLT_H
|
#define EIGEN_LDLT_H
|
||||||
|
|
||||||
// IWYU pragma: private
|
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
template <typename MatrixType_, int UpLo_>
|
template<typename MatrixType, int UpLo> struct LDLT_Traits;
|
||||||
struct traits<LDLT<MatrixType_, UpLo_> > : traits<MatrixType_> {
|
}
|
||||||
typedef MatrixXpr XprKind;
|
|
||||||
typedef SolverStorage StorageKind;
|
|
||||||
typedef int StorageIndex;
|
|
||||||
enum { Flags = 0 };
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename MatrixType, int UpLo>
|
/** \ingroup cholesky_Module
|
||||||
struct LDLT_Traits;
|
|
||||||
|
|
||||||
// PositiveSemiDef means positive semi-definite and non-zero; same for NegativeSemiDef
|
|
||||||
enum SignMatrix { PositiveSemiDef, NegativeSemiDef, ZeroSign, Indefinite };
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
/** \ingroup Cholesky_Module
|
|
||||||
*
|
*
|
||||||
* \class LDLT
|
* \class LDLT
|
||||||
*
|
*
|
||||||
* \brief Robust Cholesky decomposition of a matrix with pivoting
|
* \brief Robust Cholesky decomposition of a matrix with pivoting
|
||||||
*
|
*
|
||||||
* \tparam MatrixType_ the type of the matrix of which to compute the LDL^T Cholesky decomposition
|
* \param MatrixType the type of the matrix of which to compute the LDL^T Cholesky decomposition
|
||||||
* \tparam UpLo_ the triangular part that will be used for the decomposition: Lower (default) or Upper.
|
|
||||||
* The other triangular part won't be read.
|
|
||||||
*
|
*
|
||||||
* Perform a robust Cholesky decomposition of a positive semidefinite or negative semidefinite
|
* Perform a robust Cholesky decomposition of a positive semidefinite or negative semidefinite
|
||||||
* matrix \f$ A \f$ such that \f$ A = P^TLDL^*P \f$, where P is a permutation matrix, L
|
* 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.
|
||||||
*
|
*
|
||||||
* Remember that Cholesky decompositions are not rank-revealing. Also, do not use a Cholesky
|
* Remember that Cholesky decompositions are not rank-revealing. Also, do not use a Cholesky
|
||||||
* decomposition to determine whether a system of equations has a solution.
|
* decomposition to determine whether a system of equations has a solution.
|
||||||
*
|
*
|
||||||
* This class supports the \link InplaceDecomposition inplace decomposition \endlink mechanism.
|
* \sa MatrixBase::ldlt(), class LLT
|
||||||
*
|
|
||||||
* \sa MatrixBase::ldlt(), SelfAdjointView::ldlt(), class LLT
|
|
||||||
*/
|
*/
|
||||||
template <typename MatrixType_, int UpLo_>
|
/* THIS PART OF THE DOX IS CURRENTLY DISABLED BECAUSE INACCURATE BECAUSE OF BUG IN THE DECOMPOSITION CODE
|
||||||
class LDLT : public SolverBase<LDLT<MatrixType_, UpLo_> > {
|
* Note that during the decomposition, only the upper triangular part of A is considered. Therefore,
|
||||||
|
* the strict lower part does not have to store correct values.
|
||||||
|
*/
|
||||||
|
template<typename _MatrixType, int _UpLo> class LDLT
|
||||||
|
{
|
||||||
public:
|
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,
|
||||||
|
Options = MatrixType::Options & ~RowMajorBit, // these are the options for the TmpMatrixType, we need a ColMajor matrix here!
|
||||||
MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
|
MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
|
||||||
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
|
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
|
||||||
UpLo = UpLo_
|
UpLo = _UpLo
|
||||||
};
|
};
|
||||||
typedef Matrix<Scalar, RowsAtCompileTime, 1, 0, MaxRowsAtCompileTime, 1> TmpMatrixType;
|
typedef typename MatrixType::Scalar Scalar;
|
||||||
|
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
|
||||||
|
typedef typename MatrixType::Index Index;
|
||||||
|
typedef Matrix<Scalar, RowsAtCompileTime, 1, Options, MaxRowsAtCompileTime, 1> TmpMatrixType;
|
||||||
|
|
||||||
typedef Transpositions<RowsAtCompileTime, MaxRowsAtCompileTime> TranspositionType;
|
typedef Transpositions<RowsAtCompileTime, MaxRowsAtCompileTime> TranspositionType;
|
||||||
typedef PermutationMatrix<RowsAtCompileTime, MaxRowsAtCompileTime> PermutationType;
|
typedef PermutationMatrix<RowsAtCompileTime, MaxRowsAtCompileTime> PermutationType;
|
||||||
@@ -84,13 +83,7 @@ class LDLT : public SolverBase<LDLT<MatrixType_, UpLo_> > {
|
|||||||
* The default constructor is useful in cases in which the user intends to
|
* The default constructor is useful in cases in which the user intends to
|
||||||
* perform decompositions via LDLT::compute(const MatrixType&).
|
* perform decompositions via LDLT::compute(const MatrixType&).
|
||||||
*/
|
*/
|
||||||
LDLT()
|
LDLT() : m_matrix(), m_transpositions(), m_isInitialized(false) {}
|
||||||
: m_matrix(),
|
|
||||||
m_l1_norm(0),
|
|
||||||
m_transpositions(),
|
|
||||||
m_sign(internal::ZeroSign),
|
|
||||||
m_isInitialized(false),
|
|
||||||
m_info(InvalidInput) {}
|
|
||||||
|
|
||||||
/** \brief Default Constructor with memory preallocation
|
/** \brief Default Constructor with memory preallocation
|
||||||
*
|
*
|
||||||
@@ -98,95 +91,72 @@ class LDLT : public SolverBase<LDLT<MatrixType_, UpLo_> > {
|
|||||||
* according to the specified problem \a size.
|
* according to the specified problem \a size.
|
||||||
* \sa LDLT()
|
* \sa LDLT()
|
||||||
*/
|
*/
|
||||||
explicit LDLT(Index size)
|
LDLT(Index size)
|
||||||
: m_matrix(size, size),
|
: m_matrix(size, size),
|
||||||
m_l1_norm(0),
|
|
||||||
m_transpositions(size),
|
m_transpositions(size),
|
||||||
m_temporary(size),
|
m_temporary(size),
|
||||||
m_sign(internal::ZeroSign),
|
m_isInitialized(false)
|
||||||
m_isInitialized(false),
|
{}
|
||||||
m_info(InvalidInput) {}
|
|
||||||
|
|
||||||
/** \brief Constructor with decomposition
|
LDLT(const MatrixType& matrix)
|
||||||
*
|
|
||||||
* This calculates the decomposition for the input \a matrix.
|
|
||||||
*
|
|
||||||
* \sa LDLT(Index size)
|
|
||||||
*/
|
|
||||||
template <typename InputType>
|
|
||||||
explicit LDLT(const EigenBase<InputType>& matrix)
|
|
||||||
: m_matrix(matrix.rows(), matrix.cols()),
|
: m_matrix(matrix.rows(), matrix.cols()),
|
||||||
m_l1_norm(0),
|
|
||||||
m_transpositions(matrix.rows()),
|
m_transpositions(matrix.rows()),
|
||||||
m_temporary(matrix.rows()),
|
m_temporary(matrix.rows()),
|
||||||
m_sign(internal::ZeroSign),
|
m_isInitialized(false)
|
||||||
m_isInitialized(false),
|
{
|
||||||
m_info(InvalidInput) {
|
compute(matrix);
|
||||||
compute(matrix.derived());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Constructs a LDLT factorization from a given matrix
|
|
||||||
*
|
|
||||||
* This overloaded constructor is provided for \link InplaceDecomposition inplace decomposition \endlink when \c
|
|
||||||
* MatrixType is a Eigen::Ref.
|
|
||||||
*
|
|
||||||
* \sa LDLT(const EigenBase&)
|
|
||||||
*/
|
|
||||||
template <typename InputType>
|
|
||||||
explicit LDLT(EigenBase<InputType>& matrix)
|
|
||||||
: m_matrix(matrix.derived()),
|
|
||||||
m_l1_norm(0),
|
|
||||||
m_transpositions(matrix.rows()),
|
|
||||||
m_temporary(matrix.rows()),
|
|
||||||
m_sign(internal::ZeroSign),
|
|
||||||
m_isInitialized(false),
|
|
||||||
m_info(InvalidInput) {
|
|
||||||
compute(matrix.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Clear any existing decomposition
|
|
||||||
* \sa rankUpdate(w,sigma)
|
|
||||||
*/
|
|
||||||
void setZero() { m_isInitialized = false; }
|
|
||||||
|
|
||||||
/** \returns a view of the upper triangular matrix U */
|
/** \returns a view of the upper triangular matrix U */
|
||||||
inline typename Traits::MatrixU matrixU() const {
|
inline typename Traits::MatrixU matrixU() const
|
||||||
|
{
|
||||||
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
||||||
return Traits::getU(m_matrix);
|
return Traits::getU(m_matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns a view of the lower triangular matrix L */
|
/** \returns a view of the lower triangular matrix L */
|
||||||
inline typename Traits::MatrixL matrixL() const {
|
inline typename Traits::MatrixL matrixL() const
|
||||||
|
{
|
||||||
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
||||||
return Traits::getL(m_matrix);
|
return Traits::getL(m_matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the permutation matrix P as a transposition sequence.
|
/** \returns the permutation matrix P as a transposition sequence.
|
||||||
*/
|
*/
|
||||||
inline const TranspositionType& transpositionsP() const {
|
inline const TranspositionType& transpositionsP() const
|
||||||
|
{
|
||||||
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
||||||
return m_transpositions;
|
return m_transpositions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the coefficients of the diagonal matrix D */
|
/** \returns the coefficients of the diagonal matrix D */
|
||||||
inline Diagonal<const MatrixType> vectorD() const {
|
inline Diagonal<const MatrixType> vectorD(void) const
|
||||||
|
{
|
||||||
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
||||||
return m_matrix.diagonal();
|
return m_matrix.diagonal();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns true if the matrix is positive (semidefinite) */
|
/** \returns true if the matrix is positive (semidefinite) */
|
||||||
inline bool isPositive() const {
|
inline bool isPositive(void) const
|
||||||
|
{
|
||||||
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
||||||
return m_sign == internal::PositiveSemiDef || m_sign == internal::ZeroSign;
|
return m_sign == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef EIGEN2_SUPPORT
|
||||||
|
inline bool isPositiveDefinite() const
|
||||||
|
{
|
||||||
|
return isPositive();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/** \returns true if the matrix is negative (semidefinite) */
|
/** \returns true if the matrix is negative (semidefinite) */
|
||||||
inline bool isNegative(void) const {
|
inline bool isNegative(void) const
|
||||||
|
{
|
||||||
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
||||||
return m_sign == internal::NegativeSemiDef || m_sign == internal::ZeroSign;
|
return m_sign == -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#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> .
|
||||||
@@ -198,73 +168,50 @@ class LDLT : public SolverBase<LDLT<MatrixType_, UpLo_> > {
|
|||||||
* \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()
|
||||||
*/
|
*/
|
||||||
template<typename Rhs>
|
template<typename Rhs>
|
||||||
inline Solve<LDLT, Rhs> solve(const MatrixBase<Rhs>& b) const;
|
inline const internal::solve_retval<LDLT, Rhs>
|
||||||
|
solve(const MatrixBase<Rhs>& b) const
|
||||||
|
{
|
||||||
|
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
||||||
|
eigen_assert(m_matrix.rows()==b.rows()
|
||||||
|
&& "LDLT::solve(): invalid number of rows of the right hand side matrix b");
|
||||||
|
return internal::solve_retval<LDLT, Rhs>(*this, b.derived());
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef EIGEN2_SUPPORT
|
||||||
|
template<typename OtherDerived, typename ResultType>
|
||||||
|
bool solve(const MatrixBase<OtherDerived>& b, ResultType *result) const
|
||||||
|
{
|
||||||
|
*result = this->solve(b);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
bool solveInPlace(MatrixBase<Derived> &bAndX) const;
|
bool solveInPlace(MatrixBase<Derived> &bAndX) const;
|
||||||
|
|
||||||
template <typename InputType>
|
LDLT& compute(const MatrixType& matrix);
|
||||||
LDLT& compute(const EigenBase<InputType>& matrix);
|
|
||||||
|
|
||||||
/** \returns an estimate of the reciprocal condition number of the matrix of
|
|
||||||
* which \c *this is the LDLT decomposition.
|
|
||||||
*/
|
|
||||||
RealScalar rcond() const {
|
|
||||||
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
|
||||||
return internal::rcond_estimate_helper(m_l1_norm, *this);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Derived>
|
|
||||||
LDLT& rankUpdate(const MatrixBase<Derived>& w, const RealScalar& alpha = 1);
|
|
||||||
|
|
||||||
/** \returns the internal LDLT decomposition matrix
|
/** \returns the internal LDLT decomposition matrix
|
||||||
*
|
*
|
||||||
* TODO: document the storage layout.
|
* TODO: document the storage layout
|
||||||
*/
|
*/
|
||||||
inline const MatrixType& matrixLDLT() const {
|
inline const MatrixType& matrixLDLT() const
|
||||||
|
{
|
||||||
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
||||||
return m_matrix;
|
return m_matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
MatrixType reconstructedMatrix() const;
|
MatrixType reconstructedMatrix() const;
|
||||||
|
|
||||||
/** \returns the adjoint of \c *this, that is, a const reference to the decomposition itself as the underlying matrix
|
inline Index rows() const { return m_matrix.rows(); }
|
||||||
* is self-adjoint.
|
inline Index cols() const { return m_matrix.cols(); }
|
||||||
*
|
|
||||||
* This method is provided for compatibility with other matrix decompositions, thus enabling generic code such as:
|
|
||||||
* \code x = decomposition.adjoint().solve(b) \endcode
|
|
||||||
*/
|
|
||||||
const LDLT& adjoint() const { return *this; }
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index rows() const noexcept { return m_matrix.rows(); }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index cols() const noexcept { return m_matrix.cols(); }
|
|
||||||
|
|
||||||
/** \brief Reports whether previous computation was successful.
|
|
||||||
*
|
|
||||||
* \returns \c Success if computation was successful,
|
|
||||||
* \c NumericalIssue if the factorization failed because of a zero pivot.
|
|
||||||
*/
|
|
||||||
ComputationInfo info() const {
|
|
||||||
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
|
||||||
return m_info;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
template <typename RhsType, typename DstType>
|
|
||||||
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
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
|
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
* Used to compute and store the Cholesky decomposition A = L D L^* = U^* D U.
|
* Used to compute and store the Cholesky decomposition A = L D L^* = U^* D U.
|
||||||
@@ -273,66 +220,79 @@ class LDLT : public SolverBase<LDLT<MatrixType_, UpLo_> > {
|
|||||||
* is not stored), and the diagonal entries correspond to D.
|
* is not stored), and the diagonal entries correspond to D.
|
||||||
*/
|
*/
|
||||||
MatrixType m_matrix;
|
MatrixType m_matrix;
|
||||||
RealScalar m_l1_norm;
|
|
||||||
TranspositionType m_transpositions;
|
TranspositionType m_transpositions;
|
||||||
TmpMatrixType m_temporary;
|
TmpMatrixType m_temporary;
|
||||||
internal::SignMatrix m_sign;
|
int m_sign;
|
||||||
bool m_isInitialized;
|
bool m_isInitialized;
|
||||||
ComputationInfo m_info;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template <int UpLo>
|
template<int UpLo> struct ldlt_inplace;
|
||||||
struct ldlt_inplace;
|
|
||||||
|
|
||||||
template <>
|
template<> struct ldlt_inplace<Lower>
|
||||||
struct ldlt_inplace<Lower> {
|
{
|
||||||
template<typename MatrixType, typename TranspositionType, typename Workspace>
|
template<typename MatrixType, typename TranspositionType, typename Workspace>
|
||||||
static bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, SignMatrix& sign) {
|
static bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, int* sign=0)
|
||||||
using std::abs;
|
{
|
||||||
typedef typename MatrixType::Scalar Scalar;
|
typedef typename MatrixType::Scalar Scalar;
|
||||||
typedef typename MatrixType::RealScalar RealScalar;
|
typedef typename MatrixType::RealScalar RealScalar;
|
||||||
typedef typename TranspositionType::StorageIndex IndexType;
|
typedef typename MatrixType::Index Index;
|
||||||
eigen_assert(mat.rows()==mat.cols());
|
eigen_assert(mat.rows()==mat.cols());
|
||||||
const Index size = mat.rows();
|
const Index size = mat.rows();
|
||||||
bool found_zero_pivot = false;
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
if (size <= 1) {
|
if (size <= 1)
|
||||||
|
{
|
||||||
transpositions.setIdentity();
|
transpositions.setIdentity();
|
||||||
if (size == 0)
|
if(sign)
|
||||||
sign = ZeroSign;
|
*sign = real(mat.coeff(0,0))>0 ? 1:-1;
|
||||||
else if (numext::real(mat.coeff(0, 0)) > static_cast<RealScalar>(0))
|
|
||||||
sign = PositiveSemiDef;
|
|
||||||
else if (numext::real(mat.coeff(0, 0)) < static_cast<RealScalar>(0))
|
|
||||||
sign = NegativeSemiDef;
|
|
||||||
else
|
|
||||||
sign = ZeroSign;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Index k = 0; k < size; ++k) {
|
RealScalar cutoff = 0, biggest_in_corner;
|
||||||
|
|
||||||
|
for (Index k = 0; k < size; ++k)
|
||||||
|
{
|
||||||
// Find largest diagonal element
|
// Find largest diagonal element
|
||||||
Index index_of_biggest_in_corner;
|
Index index_of_biggest_in_corner;
|
||||||
mat.diagonal().tail(size - k).cwiseAbs().maxCoeff(&index_of_biggest_in_corner);
|
biggest_in_corner = mat.diagonal().tail(size-k).cwiseAbs().maxCoeff(&index_of_biggest_in_corner);
|
||||||
index_of_biggest_in_corner += k;
|
index_of_biggest_in_corner += k;
|
||||||
|
|
||||||
transpositions.coeffRef(k) = IndexType(index_of_biggest_in_corner);
|
if(k == 0)
|
||||||
if (k != index_of_biggest_in_corner) {
|
{
|
||||||
|
// The biggest overall is the point of reference to which further diagonals
|
||||||
|
// are compared; if any diagonal is negligible compared
|
||||||
|
// to the largest overall, the algorithm bails.
|
||||||
|
cutoff = abs(NumTraits<Scalar>::epsilon() * biggest_in_corner);
|
||||||
|
|
||||||
|
if(sign)
|
||||||
|
*sign = real(mat.diagonal().coeff(index_of_biggest_in_corner)) > 0 ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finish early if the matrix is not full rank.
|
||||||
|
if(biggest_in_corner < cutoff)
|
||||||
|
{
|
||||||
|
for(Index i = k; i < size; i++) transpositions.coeffRef(i) = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
transpositions.coeffRef(k) = index_of_biggest_in_corner;
|
||||||
|
if(k != index_of_biggest_in_corner)
|
||||||
|
{
|
||||||
// apply the transposition while taking care to consider only
|
// apply the transposition while taking care to consider only
|
||||||
// the lower triangular part
|
// the lower triangular part
|
||||||
Index s = size-index_of_biggest_in_corner-1; // trailing size after the biggest element
|
Index s = size-index_of_biggest_in_corner-1; // trailing size after the biggest element
|
||||||
mat.row(k).head(k).swap(mat.row(index_of_biggest_in_corner).head(k));
|
mat.row(k).head(k).swap(mat.row(index_of_biggest_in_corner).head(k));
|
||||||
mat.col(k).tail(s).swap(mat.col(index_of_biggest_in_corner).tail(s));
|
mat.col(k).tail(s).swap(mat.col(index_of_biggest_in_corner).tail(s));
|
||||||
std::swap(mat.coeffRef(k,k),mat.coeffRef(index_of_biggest_in_corner,index_of_biggest_in_corner));
|
std::swap(mat.coeffRef(k,k),mat.coeffRef(index_of_biggest_in_corner,index_of_biggest_in_corner));
|
||||||
for (Index i = k + 1; i < index_of_biggest_in_corner; ++i) {
|
for(int i=k+1;i<index_of_biggest_in_corner;++i)
|
||||||
|
{
|
||||||
Scalar tmp = mat.coeffRef(i,k);
|
Scalar tmp = mat.coeffRef(i,k);
|
||||||
mat.coeffRef(i, k) = numext::conj(mat.coeffRef(index_of_biggest_in_corner, i));
|
mat.coeffRef(i,k) = conj(mat.coeffRef(index_of_biggest_in_corner,i));
|
||||||
mat.coeffRef(index_of_biggest_in_corner, i) = numext::conj(tmp);
|
mat.coeffRef(index_of_biggest_in_corner,i) = conj(tmp);
|
||||||
}
|
}
|
||||||
if(NumTraits<Scalar>::IsComplex)
|
if(NumTraits<Scalar>::IsComplex)
|
||||||
mat.coeffRef(index_of_biggest_in_corner, k) = numext::conj(mat.coeff(index_of_biggest_in_corner, k));
|
mat.coeffRef(index_of_biggest_in_corner,k) = conj(mat.coeff(index_of_biggest_in_corner,k));
|
||||||
}
|
}
|
||||||
|
|
||||||
// partition the matrix:
|
// partition the matrix:
|
||||||
@@ -344,250 +304,111 @@ struct ldlt_inplace<Lower> {
|
|||||||
Block<MatrixType,1,Dynamic> A10(mat,k,0,1,k);
|
Block<MatrixType,1,Dynamic> A10(mat,k,0,1,k);
|
||||||
Block<MatrixType,Dynamic,Dynamic> A20(mat,k+1,0,rs,k);
|
Block<MatrixType,Dynamic,Dynamic> A20(mat,k+1,0,rs,k);
|
||||||
|
|
||||||
if (k > 0) {
|
if(k>0)
|
||||||
temp.head(k) = mat.diagonal().real().head(k).asDiagonal() * A10.adjoint();
|
{
|
||||||
|
temp.head(k) = mat.diagonal().head(k).asDiagonal() * A10.adjoint();
|
||||||
mat.coeffRef(k,k) -= (A10 * temp.head(k)).value();
|
mat.coeffRef(k,k) -= (A10 * temp.head(k)).value();
|
||||||
if (rs > 0) A21.noalias() -= A20 * temp.head(k);
|
if(rs>0)
|
||||||
|
A21.noalias() -= A20 * temp.head(k);
|
||||||
|
}
|
||||||
|
if((rs>0) && (abs(mat.coeffRef(k,k)) > cutoff))
|
||||||
|
A21 /= mat.coeffRef(k,k);
|
||||||
}
|
}
|
||||||
|
|
||||||
// In some previous versions of Eigen (e.g., 3.2.1), the scaling was omitted if the pivot
|
|
||||||
// was smaller than the cutoff value. However, since LDLT is not rank-revealing
|
|
||||||
// we should only make sure that we do not introduce INF or NaN values.
|
|
||||||
// Remark that LAPACK also uses 0 as the cutoff value.
|
|
||||||
RealScalar realAkk = numext::real(mat.coeffRef(k, k));
|
|
||||||
bool pivot_is_valid = (abs(realAkk) > RealScalar(0));
|
|
||||||
|
|
||||||
if (k == 0 && !pivot_is_valid) {
|
|
||||||
// The entire diagonal is zero, there is nothing more to do
|
|
||||||
// except filling the transpositions, and checking whether the matrix is zero.
|
|
||||||
sign = ZeroSign;
|
|
||||||
for (Index j = 0; j < size; ++j) {
|
|
||||||
transpositions.coeffRef(j) = IndexType(j);
|
|
||||||
ret = ret && (mat.col(j).tail(size - j - 1).array() == Scalar(0)).all();
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((rs > 0) && pivot_is_valid)
|
|
||||||
A21 /= realAkk;
|
|
||||||
else if (rs > 0)
|
|
||||||
ret = ret && (A21.array() == Scalar(0)).all();
|
|
||||||
|
|
||||||
if (found_zero_pivot && pivot_is_valid)
|
|
||||||
ret = false; // factorization failed
|
|
||||||
else if (!pivot_is_valid)
|
|
||||||
found_zero_pivot = true;
|
|
||||||
|
|
||||||
if (sign == PositiveSemiDef) {
|
|
||||||
if (realAkk < static_cast<RealScalar>(0)) sign = Indefinite;
|
|
||||||
} else if (sign == NegativeSemiDef) {
|
|
||||||
if (realAkk > static_cast<RealScalar>(0)) sign = Indefinite;
|
|
||||||
} else if (sign == ZeroSign) {
|
|
||||||
if (realAkk > static_cast<RealScalar>(0))
|
|
||||||
sign = PositiveSemiDef;
|
|
||||||
else if (realAkk < static_cast<RealScalar>(0))
|
|
||||||
sign = NegativeSemiDef;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reference for the algorithm: Davis and Hager, "Multiple Rank
|
|
||||||
// Modifications of a Sparse Cholesky Factorization" (Algorithm 1)
|
|
||||||
// Trivial rearrangements of their computations (Timothy E. Holy)
|
|
||||||
// allow their algorithm to work for rank-1 updates even if the
|
|
||||||
// original matrix is not of full rank.
|
|
||||||
// Here only rank-1 updates are implemented, to reduce the
|
|
||||||
// requirement for intermediate storage and improve accuracy
|
|
||||||
template <typename MatrixType, typename WDerived>
|
|
||||||
static bool updateInPlace(MatrixType& mat, MatrixBase<WDerived>& w,
|
|
||||||
const typename MatrixType::RealScalar& sigma = 1) {
|
|
||||||
using numext::isfinite;
|
|
||||||
typedef typename MatrixType::Scalar Scalar;
|
|
||||||
typedef typename MatrixType::RealScalar RealScalar;
|
|
||||||
|
|
||||||
const Index size = mat.rows();
|
|
||||||
eigen_assert(mat.cols() == size && w.size() == size);
|
|
||||||
|
|
||||||
RealScalar alpha = 1;
|
|
||||||
|
|
||||||
// Apply the update
|
|
||||||
for (Index j = 0; j < size; j++) {
|
|
||||||
// Check for termination due to an original decomposition of low-rank
|
|
||||||
if (!(isfinite)(alpha)) break;
|
|
||||||
|
|
||||||
// Update the diagonal terms
|
|
||||||
RealScalar dj = numext::real(mat.coeff(j, j));
|
|
||||||
Scalar wj = w.coeff(j);
|
|
||||||
RealScalar swj2 = sigma * numext::abs2(wj);
|
|
||||||
RealScalar gamma = dj * alpha + swj2;
|
|
||||||
|
|
||||||
mat.coeffRef(j, j) += swj2 / alpha;
|
|
||||||
alpha += swj2 / dj;
|
|
||||||
|
|
||||||
// Update the terms of L
|
|
||||||
Index rs = size - j - 1;
|
|
||||||
w.tail(rs) -= wj * mat.col(j).tail(rs);
|
|
||||||
if (!numext::is_exactly_zero(gamma)) mat.col(j).tail(rs) += (sigma * numext::conj(wj) / gamma) * w.tail(rs);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename MatrixType, typename TranspositionType, typename Workspace, typename WType>
|
|
||||||
static bool update(MatrixType& mat, const TranspositionType& transpositions, Workspace& tmp, const WType& w,
|
|
||||||
const typename MatrixType::RealScalar& sigma = 1) {
|
|
||||||
// Apply the permutation to the input w
|
|
||||||
tmp = transpositions * w;
|
|
||||||
|
|
||||||
return ldlt_inplace<Lower>::updateInPlace(mat, tmp, sigma);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template<> struct ldlt_inplace<Upper>
|
||||||
struct ldlt_inplace<Upper> {
|
{
|
||||||
template<typename MatrixType, typename TranspositionType, typename Workspace>
|
template<typename MatrixType, typename TranspositionType, typename Workspace>
|
||||||
static EIGEN_STRONG_INLINE bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp,
|
static EIGEN_STRONG_INLINE bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, int* sign=0)
|
||||||
SignMatrix& sign) {
|
{
|
||||||
Transpose<MatrixType> matt(mat);
|
Transpose<MatrixType> matt(mat);
|
||||||
return ldlt_inplace<Lower>::unblocked(matt, transpositions, temp, sign);
|
return ldlt_inplace<Lower>::unblocked(matt, transpositions, temp, sign);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename MatrixType, typename TranspositionType, typename Workspace, typename WType>
|
|
||||||
static EIGEN_STRONG_INLINE bool update(MatrixType& mat, TranspositionType& transpositions, Workspace& tmp, WType& w,
|
|
||||||
const typename MatrixType::RealScalar& sigma = 1) {
|
|
||||||
Transpose<MatrixType> matt(mat);
|
|
||||||
return ldlt_inplace<Lower>::update(matt, transpositions, tmp, w.conjugate(), sigma);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename MatrixType>
|
template<typename MatrixType> struct LDLT_Traits<MatrixType,Lower>
|
||||||
struct LDLT_Traits<MatrixType, Lower> {
|
{
|
||||||
typedef const TriangularView<const MatrixType, UnitLower> MatrixL;
|
typedef const TriangularView<const MatrixType, UnitLower> MatrixL;
|
||||||
typedef const TriangularView<const typename MatrixType::AdjointReturnType, UnitUpper> MatrixU;
|
typedef const TriangularView<const typename MatrixType::AdjointReturnType, UnitUpper> MatrixU;
|
||||||
static inline MatrixL getL(const MatrixType& m) { return MatrixL(m); }
|
inline static MatrixL getL(const MatrixType& m) { return m; }
|
||||||
static inline MatrixU getU(const MatrixType& m) { return MatrixU(m.adjoint()); }
|
inline static MatrixU getU(const MatrixType& m) { return m.adjoint(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename MatrixType>
|
template<typename MatrixType> struct LDLT_Traits<MatrixType,Upper>
|
||||||
struct LDLT_Traits<MatrixType, Upper> {
|
{
|
||||||
typedef const TriangularView<const typename MatrixType::AdjointReturnType, UnitLower> MatrixL;
|
typedef const TriangularView<const typename MatrixType::AdjointReturnType, UnitLower> MatrixL;
|
||||||
typedef const TriangularView<const MatrixType, UnitUpper> MatrixU;
|
typedef const TriangularView<const MatrixType, UnitUpper> MatrixU;
|
||||||
static inline MatrixL getL(const MatrixType& m) { return MatrixL(m.adjoint()); }
|
inline static MatrixL getL(const MatrixType& m) { return m.adjoint(); }
|
||||||
static inline MatrixU getU(const MatrixType& m) { return MatrixU(m); }
|
inline static MatrixU getU(const MatrixType& m) { return m; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
/** Compute / recompute the LDLT decomposition A = L D L^* = U^* D U of \a matrix
|
/** Compute / recompute the LDLT decomposition A = L D L^* = U^* D U of \a matrix
|
||||||
*/
|
*/
|
||||||
template <typename MatrixType, int UpLo_>
|
template<typename MatrixType, int _UpLo>
|
||||||
template <typename InputType>
|
LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::compute(const MatrixType& a)
|
||||||
LDLT<MatrixType, UpLo_>& LDLT<MatrixType, UpLo_>::compute(const EigenBase<InputType>& a) {
|
{
|
||||||
eigen_assert(a.rows()==a.cols());
|
eigen_assert(a.rows()==a.cols());
|
||||||
const Index size = a.rows();
|
const Index size = a.rows();
|
||||||
|
|
||||||
m_matrix = a.derived();
|
m_matrix = a;
|
||||||
|
|
||||||
// Compute matrix L1 norm = max abs column sum.
|
|
||||||
m_l1_norm = RealScalar(0);
|
|
||||||
// TODO: move this code to SelfAdjointView
|
|
||||||
for (Index col = 0; col < size; ++col) {
|
|
||||||
RealScalar abs_col_sum;
|
|
||||||
if (UpLo_ == Lower)
|
|
||||||
abs_col_sum =
|
|
||||||
m_matrix.col(col).tail(size - col).template lpNorm<1>() + m_matrix.row(col).head(col).template lpNorm<1>();
|
|
||||||
else
|
|
||||||
abs_col_sum =
|
|
||||||
m_matrix.col(col).head(col).template lpNorm<1>() + m_matrix.row(col).tail(size - col).template lpNorm<1>();
|
|
||||||
if (abs_col_sum > m_l1_norm) m_l1_norm = abs_col_sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_transpositions.resize(size);
|
m_transpositions.resize(size);
|
||||||
m_isInitialized = false;
|
m_isInitialized = false;
|
||||||
m_temporary.resize(size);
|
m_temporary.resize(size);
|
||||||
m_sign = internal::ZeroSign;
|
|
||||||
|
|
||||||
m_info = internal::ldlt_inplace<UpLo>::unblocked(m_matrix, m_transpositions, m_temporary, m_sign) ? Success
|
internal::ldlt_inplace<UpLo>::unblocked(m_matrix, m_transpositions, m_temporary, &m_sign);
|
||||||
: NumericalIssue;
|
|
||||||
|
|
||||||
m_isInitialized = true;
|
m_isInitialized = true;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Update the LDLT decomposition: given A = L D L^T, efficiently compute the decomposition of A + sigma w w^T.
|
namespace internal {
|
||||||
* \param w a vector to be incorporated into the decomposition.
|
template<typename _MatrixType, int _UpLo, typename Rhs>
|
||||||
* \param sigma a scalar, +1 for updates and -1 for "downdates," which correspond to removing previously-added column
|
struct solve_retval<LDLT<_MatrixType,_UpLo>, Rhs>
|
||||||
* vectors. Optional; default value is +1. \sa setZero()
|
: solve_retval_base<LDLT<_MatrixType,_UpLo>, Rhs>
|
||||||
*/
|
{
|
||||||
template <typename MatrixType, int UpLo_>
|
typedef LDLT<_MatrixType,_UpLo> LDLTType;
|
||||||
template <typename Derived>
|
EIGEN_MAKE_SOLVE_HELPERS(LDLTType,Rhs)
|
||||||
LDLT<MatrixType, UpLo_>& LDLT<MatrixType, UpLo_>::rankUpdate(
|
|
||||||
const MatrixBase<Derived>& w, const typename LDLT<MatrixType, UpLo_>::RealScalar& sigma) {
|
|
||||||
typedef typename TranspositionType::StorageIndex IndexType;
|
|
||||||
const Index size = w.rows();
|
|
||||||
if (m_isInitialized) {
|
|
||||||
eigen_assert(m_matrix.rows() == size);
|
|
||||||
} else {
|
|
||||||
m_matrix.resize(size, size);
|
|
||||||
m_matrix.setZero();
|
|
||||||
m_transpositions.resize(size);
|
|
||||||
for (Index i = 0; i < size; i++) m_transpositions.coeffRef(i) = IndexType(i);
|
|
||||||
m_temporary.resize(size);
|
|
||||||
m_sign = sigma >= 0 ? internal::PositiveSemiDef : internal::NegativeSemiDef;
|
|
||||||
m_isInitialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal::ldlt_inplace<UpLo>::update(m_matrix, m_transpositions, m_temporary, w, sigma);
|
template<typename Dest> void evalTo(Dest& dst) const
|
||||||
|
{
|
||||||
return *this;
|
eigen_assert(rhs().rows() == dec().matrixLDLT().rows());
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
template <typename MatrixType_, int UpLo_>
|
|
||||||
template <typename RhsType, typename DstType>
|
|
||||||
void LDLT<MatrixType_, UpLo_>::_solve_impl(const RhsType& rhs, DstType& dst) const {
|
|
||||||
_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 {
|
|
||||||
// dst = P b
|
// dst = P b
|
||||||
dst = m_transpositions * rhs;
|
dst = dec().transpositionsP() * rhs();
|
||||||
|
|
||||||
// dst = L^-1 (P b)
|
// dst = L^-1 (P b)
|
||||||
// dst = L^-*T (P b)
|
dec().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());
|
using std::max;
|
||||||
// In some previous versions, tolerance was set to the max of 1/highest (or rather numeric_limits::min())
|
typedef typename LDLTType::MatrixType MatrixType;
|
||||||
// and the maximal diagonal entry * epsilon as motivated by LAPACK's xGELSS:
|
typedef typename LDLTType::Scalar Scalar;
|
||||||
// RealScalar tolerance = numext::maxi(vecD.array().abs().maxCoeff() * NumTraits<RealScalar>::epsilon(),RealScalar(1)
|
typedef typename LDLTType::RealScalar RealScalar;
|
||||||
// / NumTraits<RealScalar>::highest()); However, LDLT is not rank revealing, and so adjusting the tolerance wrt to the
|
const Diagonal<const MatrixType> vectorD = dec().vectorD();
|
||||||
// highest diagonal element is not well justified and leads to numerical issues in some cases. Moreover, Lapack's
|
RealScalar tolerance = (max)(vectorD.array().abs().maxCoeff() * NumTraits<Scalar>::epsilon(),
|
||||||
// xSYTRS routines use 0 for the tolerance. Using numeric_limits::min() gives us more robustness to denormals.
|
RealScalar(1) / NumTraits<RealScalar>::highest()); // motivated by LAPACK's xGELSS
|
||||||
RealScalar tolerance = (std::numeric_limits<RealScalar>::min)();
|
for (Index i = 0; i < vectorD.size(); ++i) {
|
||||||
for (Index i = 0; i < vecD.size(); ++i) {
|
if(abs(vectorD(i)) > tolerance)
|
||||||
if (abs(vecD(i)) > tolerance)
|
dst.row(i) /= vectorD(i);
|
||||||
dst.row(i) /= vecD(i);
|
|
||||||
else
|
else
|
||||||
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)
|
dec().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 = dec().transpositionsP().transpose() * dst;
|
||||||
dst = m_transpositions.transpose() * dst;
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \internal use x = ldlt_object.solve(x);
|
/** \internal use x = ldlt_object.solve(x);
|
||||||
*
|
*
|
||||||
@@ -602,11 +423,13 @@ void LDLT<MatrixType_, UpLo_>::_solve_impl_transposed(const RhsType& rhs, DstTyp
|
|||||||
*
|
*
|
||||||
* \sa LDLT::solve(), MatrixBase::ldlt()
|
* \sa LDLT::solve(), MatrixBase::ldlt()
|
||||||
*/
|
*/
|
||||||
template <typename MatrixType, int UpLo_>
|
template<typename MatrixType,int _UpLo>
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
bool LDLT<MatrixType, UpLo_>::solveInPlace(MatrixBase<Derived>& bAndX) const {
|
bool LDLT<MatrixType,_UpLo>::solveInPlace(MatrixBase<Derived> &bAndX) const
|
||||||
|
{
|
||||||
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
||||||
eigen_assert(m_matrix.rows() == bAndX.rows());
|
const Index size = m_matrix.rows();
|
||||||
|
eigen_assert(size == bAndX.rows());
|
||||||
|
|
||||||
bAndX = this->solve(bAndX);
|
bAndX = this->solve(bAndX);
|
||||||
|
|
||||||
@@ -616,8 +439,9 @@ bool LDLT<MatrixType, UpLo_>::solveInPlace(MatrixBase<Derived>& bAndX) const {
|
|||||||
/** \returns the matrix represented by the decomposition,
|
/** \returns the matrix represented by the decomposition,
|
||||||
* i.e., it returns the product: P^T L D L^* P.
|
* i.e., it returns the product: P^T L D L^* P.
|
||||||
* This function is provided for debug purpose. */
|
* This function is provided for debug purpose. */
|
||||||
template <typename MatrixType, int UpLo_>
|
template<typename MatrixType, int _UpLo>
|
||||||
MatrixType LDLT<MatrixType, UpLo_>::reconstructedMatrix() const {
|
MatrixType LDLT<MatrixType,_UpLo>::reconstructedMatrix() const
|
||||||
|
{
|
||||||
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
||||||
const Index size = m_matrix.rows();
|
const Index size = m_matrix.rows();
|
||||||
MatrixType res(size,size);
|
MatrixType res(size,size);
|
||||||
@@ -628,7 +452,7 @@ MatrixType LDLT<MatrixType, UpLo_>::reconstructedMatrix() const {
|
|||||||
// L^* P
|
// L^* P
|
||||||
res = matrixU() * res;
|
res = matrixU() * res;
|
||||||
// D(L^*P)
|
// D(L^*P)
|
||||||
res = vectorD().real().asDiagonal() * res;
|
res = vectorD().asDiagonal() * res;
|
||||||
// L(DL^*P)
|
// L(DL^*P)
|
||||||
res = matrixL() * res;
|
res = matrixL() * res;
|
||||||
// P^T (LDL^*P)
|
// P^T (LDL^*P)
|
||||||
@@ -639,23 +463,22 @@ MatrixType LDLT<MatrixType, UpLo_>::reconstructedMatrix() const {
|
|||||||
|
|
||||||
/** \cholesky_module
|
/** \cholesky_module
|
||||||
* \returns the Cholesky decomposition with full pivoting without square root of \c *this
|
* \returns the Cholesky decomposition with full pivoting without square root of \c *this
|
||||||
* \sa MatrixBase::ldlt()
|
|
||||||
*/
|
*/
|
||||||
template<typename MatrixType, unsigned int UpLo>
|
template<typename MatrixType, unsigned int UpLo>
|
||||||
inline LDLT<typename SelfAdjointView<MatrixType, UpLo>::PlainObject, UpLo> SelfAdjointView<MatrixType, UpLo>::ldlt()
|
inline const LDLT<typename SelfAdjointView<MatrixType, UpLo>::PlainObject, UpLo>
|
||||||
const {
|
SelfAdjointView<MatrixType, UpLo>::ldlt() const
|
||||||
|
{
|
||||||
return LDLT<PlainObject,UpLo>(m_matrix);
|
return LDLT<PlainObject,UpLo>(m_matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \cholesky_module
|
/** \cholesky_module
|
||||||
* \returns the Cholesky decomposition with full pivoting without square root of \c *this
|
* \returns the Cholesky decomposition with full pivoting without square root of \c *this
|
||||||
* \sa SelfAdjointView::ldlt()
|
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline LDLT<typename MatrixBase<Derived>::PlainObject> MatrixBase<Derived>::ldlt() const {
|
inline const LDLT<typename MatrixBase<Derived>::PlainObject>
|
||||||
|
MatrixBase<Derived>::ldlt() const
|
||||||
|
{
|
||||||
return LDLT<PlainObject>(derived());
|
return LDLT<PlainObject>(derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_LDLT_H
|
#endif // EIGEN_LDLT_H
|
||||||
|
|||||||
@@ -3,41 +3,39 @@
|
|||||||
//
|
//
|
||||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_LLT_H
|
#ifndef EIGEN_LLT_H
|
||||||
#define EIGEN_LLT_H
|
#define EIGEN_LLT_H
|
||||||
|
|
||||||
// IWYU pragma: private
|
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
namespace internal{
|
namespace internal{
|
||||||
|
template<typename MatrixType, int UpLo> struct LLT_Traits;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename MatrixType_, int UpLo_>
|
/** \ingroup cholesky_Module
|
||||||
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;
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
/** \ingroup Cholesky_Module
|
|
||||||
*
|
*
|
||||||
* \class LLT
|
* \class LLT
|
||||||
*
|
*
|
||||||
* \brief Standard Cholesky decomposition (LL^T) of a matrix and associated features
|
* \brief Standard Cholesky decomposition (LL^T) of a matrix and associated features
|
||||||
*
|
*
|
||||||
* \tparam MatrixType_ the type of the matrix of which we are computing the LL^T Cholesky decomposition
|
* \param MatrixType the type of the matrix of which we are computing the LL^T Cholesky decomposition
|
||||||
* \tparam UpLo_ the triangular part that will be used for the decomposition: Lower (default) or Upper.
|
|
||||||
* The other triangular part won't be read.
|
|
||||||
*
|
*
|
||||||
* This class performs a LL^T Cholesky decomposition of a symmetric, positive definite
|
* This class performs a LL^T Cholesky decomposition of a symmetric, positive definite
|
||||||
* matrix A such that A = LL^* = U^*U, where L is lower triangular.
|
* matrix A such that A = LL^* = U^*U, where L is lower triangular.
|
||||||
@@ -47,36 +45,35 @@ struct LLT_Traits;
|
|||||||
* and even faster. Nevertheless, this standard Cholesky decomposition remains useful in many other
|
* and even faster. Nevertheless, this standard Cholesky decomposition remains useful in many other
|
||||||
* situations like generalised eigen problems with hermitian matrices.
|
* situations like generalised eigen problems with hermitian matrices.
|
||||||
*
|
*
|
||||||
* Remember that Cholesky decompositions are not rank-revealing. This LLT decomposition is only stable on positive
|
* Remember that Cholesky decompositions are not rank-revealing. This LLT decomposition is only stable on positive definite matrices,
|
||||||
* definite matrices, use LDLT instead for the semidefinite case. Also, do not use a Cholesky decomposition to determine
|
* use LDLT instead for the semidefinite case. Also, do not use a Cholesky decomposition to determine whether a system of equations
|
||||||
* whether a system of equations has a solution.
|
* has a solution.
|
||||||
*
|
*
|
||||||
* Example: \include LLT_example.cpp
|
* \sa MatrixBase::llt(), class LDLT
|
||||||
* Output: \verbinclude LLT_example.out
|
|
||||||
*
|
|
||||||
* \b Performance: for best performance, it is recommended to use a column-major storage format
|
|
||||||
* with the Lower triangular part (the default), or, equivalently, a row-major storage format
|
|
||||||
* with the Upper triangular part. Otherwise, you might get a 20% slowdown for the full factorization
|
|
||||||
* step, and rank-updates can be up to 3 times slower.
|
|
||||||
*
|
|
||||||
* This class supports the \link InplaceDecomposition inplace decomposition \endlink mechanism.
|
|
||||||
*
|
|
||||||
* Note that during the decomposition, only the lower (or upper, as defined by UpLo_) triangular part of A is
|
|
||||||
* considered. Therefore, the strict lower part does not have to store correct values.
|
|
||||||
*
|
|
||||||
* \sa MatrixBase::llt(), SelfAdjointView::llt(), class LDLT
|
|
||||||
*/
|
*/
|
||||||
template <typename MatrixType_, int UpLo_>
|
/* HEY THIS DOX IS DISABLED BECAUSE THERE's A BUG EITHER HERE OR IN LDLT ABOUT THAT (OR BOTH)
|
||||||
class LLT : public SolverBase<LLT<MatrixType_, UpLo_> > {
|
* Note that during the decomposition, only the upper triangular part of A is considered. Therefore,
|
||||||
|
* the strict lower part does not have to store correct values.
|
||||||
|
*/
|
||||||
|
template<typename _MatrixType, int _UpLo> class LLT
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
typedef MatrixType_ MatrixType;
|
typedef _MatrixType MatrixType;
|
||||||
typedef SolverBase<LLT> Base;
|
enum {
|
||||||
friend class SolverBase<LLT>;
|
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
|
||||||
|
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
|
||||||
|
Options = MatrixType::Options,
|
||||||
|
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
|
||||||
|
};
|
||||||
|
typedef typename MatrixType::Scalar Scalar;
|
||||||
|
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
|
||||||
|
typedef typename MatrixType::Index Index;
|
||||||
|
|
||||||
EIGEN_GENERIC_PUBLIC_INTERFACE(LLT)
|
enum {
|
||||||
enum { MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime };
|
PacketSize = internal::packet_traits<Scalar>::size,
|
||||||
|
AlignmentMask = int(PacketSize)-1,
|
||||||
enum { PacketSize = internal::packet_traits<Scalar>::size, AlignmentMask = int(PacketSize) - 1, UpLo = UpLo_ };
|
UpLo = _UpLo
|
||||||
|
};
|
||||||
|
|
||||||
typedef internal::LLT_Traits<MatrixType,UpLo> Traits;
|
typedef internal::LLT_Traits<MatrixType,UpLo> Traits;
|
||||||
|
|
||||||
@@ -86,7 +83,7 @@ class LLT : public SolverBase<LLT<MatrixType_, UpLo_> > {
|
|||||||
* The default constructor is useful in cases in which the user intends to
|
* The default constructor is useful in cases in which the user intends to
|
||||||
* perform decompositions via LLT::compute(const MatrixType&).
|
* perform decompositions via LLT::compute(const MatrixType&).
|
||||||
*/
|
*/
|
||||||
LLT() : m_matrix(), m_l1_norm(0), m_isInitialized(false), m_info(InvalidInput) {}
|
LLT() : m_matrix(), m_isInitialized(false) {}
|
||||||
|
|
||||||
/** \brief Default Constructor with memory preallocation
|
/** \brief Default Constructor with memory preallocation
|
||||||
*
|
*
|
||||||
@@ -94,40 +91,30 @@ class LLT : public SolverBase<LLT<MatrixType_, UpLo_> > {
|
|||||||
* according to the specified problem \a size.
|
* according to the specified problem \a size.
|
||||||
* \sa LLT()
|
* \sa LLT()
|
||||||
*/
|
*/
|
||||||
explicit LLT(Index size) : m_matrix(size, size), m_l1_norm(0), m_isInitialized(false), m_info(InvalidInput) {}
|
LLT(Index size) : m_matrix(size, size),
|
||||||
|
m_isInitialized(false) {}
|
||||||
|
|
||||||
template <typename InputType>
|
LLT(const MatrixType& matrix)
|
||||||
explicit LLT(const EigenBase<InputType>& matrix)
|
: m_matrix(matrix.rows(), matrix.cols()),
|
||||||
: m_matrix(matrix.rows(), matrix.cols()), m_l1_norm(0), m_isInitialized(false), m_info(InvalidInput) {
|
m_isInitialized(false)
|
||||||
compute(matrix.derived());
|
{
|
||||||
}
|
compute(matrix);
|
||||||
|
|
||||||
/** \brief Constructs a LLT factorization from a given matrix
|
|
||||||
*
|
|
||||||
* This overloaded constructor is provided for \link InplaceDecomposition inplace decomposition \endlink when
|
|
||||||
* \c MatrixType is a Eigen::Ref.
|
|
||||||
*
|
|
||||||
* \sa LLT(const EigenBase&)
|
|
||||||
*/
|
|
||||||
template <typename InputType>
|
|
||||||
explicit LLT(EigenBase<InputType>& matrix)
|
|
||||||
: m_matrix(matrix.derived()), m_l1_norm(0), m_isInitialized(false), m_info(InvalidInput) {
|
|
||||||
compute(matrix.derived());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns a view of the upper triangular matrix U */
|
/** \returns a view of the upper triangular matrix U */
|
||||||
inline typename Traits::MatrixU matrixU() const {
|
inline typename Traits::MatrixU matrixU() const
|
||||||
|
{
|
||||||
eigen_assert(m_isInitialized && "LLT is not initialized.");
|
eigen_assert(m_isInitialized && "LLT is not initialized.");
|
||||||
return Traits::getU(m_matrix);
|
return Traits::getU(m_matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns a view of the lower triangular matrix L */
|
/** \returns a view of the lower triangular matrix L */
|
||||||
inline typename Traits::MatrixL matrixL() const {
|
inline typename Traits::MatrixL matrixL() const
|
||||||
|
{
|
||||||
eigen_assert(m_isInitialized && "LLT is not initialized.");
|
eigen_assert(m_isInitialized && "LLT is not initialized.");
|
||||||
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
|
||||||
@@ -136,188 +123,120 @@ class LLT : public SolverBase<LLT<MatrixType_, UpLo_> > {
|
|||||||
* Example: \include LLT_solve.cpp
|
* Example: \include LLT_solve.cpp
|
||||||
* Output: \verbinclude LLT_solve.out
|
* Output: \verbinclude LLT_solve.out
|
||||||
*
|
*
|
||||||
* \sa solveInPlace(), MatrixBase::llt(), SelfAdjointView::llt()
|
* \sa solveInPlace(), MatrixBase::llt()
|
||||||
*/
|
*/
|
||||||
template<typename Rhs>
|
template<typename Rhs>
|
||||||
inline Solve<LLT, Rhs> solve(const MatrixBase<Rhs>& b) const;
|
inline const internal::solve_retval<LLT, Rhs>
|
||||||
|
solve(const MatrixBase<Rhs>& b) const
|
||||||
|
{
|
||||||
|
eigen_assert(m_isInitialized && "LLT is not initialized.");
|
||||||
|
eigen_assert(m_matrix.rows()==b.rows()
|
||||||
|
&& "LLT::solve(): invalid number of rows of the right hand side matrix b");
|
||||||
|
return internal::solve_retval<LLT, Rhs>(*this, b.derived());
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef EIGEN2_SUPPORT
|
||||||
|
template<typename OtherDerived, typename ResultType>
|
||||||
|
bool solve(const MatrixBase<OtherDerived>& b, ResultType *result) const
|
||||||
|
{
|
||||||
|
*result = this->solve(b);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isPositiveDefinite() const { return true; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
void solveInPlace(const MatrixBase<Derived>& bAndX) const;
|
void solveInPlace(MatrixBase<Derived> &bAndX) const;
|
||||||
|
|
||||||
template <typename InputType>
|
LLT& compute(const MatrixType& matrix);
|
||||||
LLT& compute(const EigenBase<InputType>& matrix);
|
|
||||||
|
|
||||||
/** \returns an estimate of the reciprocal condition number of the matrix of
|
|
||||||
* which \c *this is the Cholesky decomposition.
|
|
||||||
*/
|
|
||||||
RealScalar rcond() const {
|
|
||||||
eigen_assert(m_isInitialized && "LLT is not initialized.");
|
|
||||||
eigen_assert(m_info == Success && "LLT failed because matrix appears to be negative");
|
|
||||||
return internal::rcond_estimate_helper(m_l1_norm, *this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \returns the LLT decomposition matrix
|
/** \returns the LLT decomposition matrix
|
||||||
*
|
*
|
||||||
* TODO: document the storage layout
|
* TODO: document the storage layout
|
||||||
*/
|
*/
|
||||||
inline const MatrixType& matrixLLT() const {
|
inline const MatrixType& matrixLLT() const
|
||||||
|
{
|
||||||
eigen_assert(m_isInitialized && "LLT is not initialized.");
|
eigen_assert(m_isInitialized && "LLT is not initialized.");
|
||||||
return m_matrix;
|
return m_matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
MatrixType reconstructedMatrix() const;
|
MatrixType reconstructedMatrix() const;
|
||||||
|
|
||||||
|
|
||||||
/** \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 to be negative.
|
||||||
*/
|
*/
|
||||||
ComputationInfo info() const {
|
ComputationInfo info() const
|
||||||
|
{
|
||||||
eigen_assert(m_isInitialized && "LLT is not initialized.");
|
eigen_assert(m_isInitialized && "LLT is not initialized.");
|
||||||
return m_info;
|
return m_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the adjoint of \c *this, that is, a const reference to the decomposition itself as the underlying matrix
|
inline Index rows() const { return m_matrix.rows(); }
|
||||||
* is self-adjoint.
|
inline Index cols() const { return m_matrix.cols(); }
|
||||||
*
|
|
||||||
* This method is provided for compatibility with other matrix decompositions, thus enabling generic code such as:
|
|
||||||
* \code x = decomposition.adjoint().solve(b) \endcode
|
|
||||||
*/
|
|
||||||
const LLT& adjoint() const noexcept { return *this; }
|
|
||||||
|
|
||||||
constexpr Index rows() const noexcept { return m_matrix.rows(); }
|
|
||||||
constexpr Index cols() const noexcept { return m_matrix.cols(); }
|
|
||||||
|
|
||||||
template <typename VectorType>
|
|
||||||
LLT& rankUpdate(const VectorType& vec, const RealScalar& sigma = 1);
|
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
template <typename RhsType, typename DstType>
|
|
||||||
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
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
|
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
* Used to compute and store L
|
* Used to compute and store L
|
||||||
* The strict upper part is not used and even not initialized.
|
* The strict upper part is not used and even not initialized.
|
||||||
*/
|
*/
|
||||||
MatrixType m_matrix;
|
MatrixType m_matrix;
|
||||||
RealScalar m_l1_norm;
|
|
||||||
bool m_isInitialized;
|
bool m_isInitialized;
|
||||||
ComputationInfo m_info;
|
ComputationInfo m_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template <typename Scalar, int UpLo>
|
template<int UpLo> struct llt_inplace;
|
||||||
struct llt_inplace;
|
|
||||||
|
|
||||||
template <typename MatrixType, typename VectorType>
|
template<> struct llt_inplace<Lower>
|
||||||
static Index llt_rank_update_lower(MatrixType& mat, const VectorType& vec,
|
{
|
||||||
const typename MatrixType::RealScalar& sigma) {
|
template<typename MatrixType>
|
||||||
using std::sqrt;
|
static typename MatrixType::Index unblocked(MatrixType& mat)
|
||||||
|
{
|
||||||
|
typedef typename MatrixType::Index Index;
|
||||||
typedef typename MatrixType::Scalar Scalar;
|
typedef typename MatrixType::Scalar Scalar;
|
||||||
typedef typename MatrixType::RealScalar RealScalar;
|
typedef typename MatrixType::RealScalar RealScalar;
|
||||||
typedef typename MatrixType::ColXpr ColXpr;
|
|
||||||
typedef internal::remove_all_t<ColXpr> ColXprCleaned;
|
|
||||||
typedef typename ColXprCleaned::SegmentReturnType ColXprSegment;
|
|
||||||
typedef Matrix<Scalar, Dynamic, 1> TempVectorType;
|
|
||||||
typedef typename TempVectorType::SegmentReturnType TempVecSegment;
|
|
||||||
|
|
||||||
Index n = mat.cols();
|
|
||||||
eigen_assert(mat.rows() == n && vec.size() == n);
|
|
||||||
|
|
||||||
TempVectorType temp;
|
|
||||||
|
|
||||||
if (sigma > 0) {
|
|
||||||
// This version is based on Givens rotations.
|
|
||||||
// It is faster than the other one below, but only works for updates,
|
|
||||||
// i.e., for sigma > 0
|
|
||||||
temp = sqrt(sigma) * vec;
|
|
||||||
|
|
||||||
for (Index i = 0; i < n; ++i) {
|
|
||||||
JacobiRotation<Scalar> g;
|
|
||||||
g.makeGivens(mat(i, i), -temp(i), &mat(i, i));
|
|
||||||
|
|
||||||
Index rs = n - i - 1;
|
|
||||||
if (rs > 0) {
|
|
||||||
ColXprSegment x(mat.col(i).tail(rs));
|
|
||||||
TempVecSegment y(temp.tail(rs));
|
|
||||||
apply_rotation_in_the_plane(x, y, g);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
temp = vec;
|
|
||||||
RealScalar beta = 1;
|
|
||||||
for (Index j = 0; j < n; ++j) {
|
|
||||||
RealScalar Ljj = numext::real(mat.coeff(j, j));
|
|
||||||
RealScalar dj = numext::abs2(Ljj);
|
|
||||||
Scalar wj = temp.coeff(j);
|
|
||||||
RealScalar swj2 = sigma * numext::abs2(wj);
|
|
||||||
RealScalar gamma = dj * beta + swj2;
|
|
||||||
|
|
||||||
RealScalar x = dj + swj2 / beta;
|
|
||||||
if (x <= RealScalar(0)) return j;
|
|
||||||
RealScalar nLjj = sqrt(x);
|
|
||||||
mat.coeffRef(j, j) = nLjj;
|
|
||||||
beta += swj2 / dj;
|
|
||||||
|
|
||||||
// Update the terms of L
|
|
||||||
Index rs = n - j - 1;
|
|
||||||
if (rs) {
|
|
||||||
temp.tail(rs) -= (wj / Ljj) * mat.col(j).tail(rs);
|
|
||||||
if (!numext::is_exactly_zero(gamma))
|
|
||||||
mat.col(j).tail(rs) =
|
|
||||||
(nLjj / Ljj) * mat.col(j).tail(rs) + (nLjj * sigma * numext::conj(wj) / gamma) * temp.tail(rs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Scalar>
|
|
||||||
struct llt_inplace<Scalar, Lower> {
|
|
||||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
|
||||||
template <typename MatrixType>
|
|
||||||
static Index unblocked(MatrixType& mat) {
|
|
||||||
using std::sqrt;
|
|
||||||
|
|
||||||
eigen_assert(mat.rows()==mat.cols());
|
eigen_assert(mat.rows()==mat.cols());
|
||||||
const Index size = mat.rows();
|
const Index size = mat.rows();
|
||||||
for (Index k = 0; k < size; ++k) {
|
for(Index k = 0; k < size; ++k)
|
||||||
|
{
|
||||||
Index rs = size-k-1; // remaining size
|
Index rs = size-k-1; // remaining size
|
||||||
|
|
||||||
Block<MatrixType,Dynamic,1> A21(mat,k+1,k,rs,1);
|
Block<MatrixType,Dynamic,1> A21(mat,k+1,k,rs,1);
|
||||||
Block<MatrixType,1,Dynamic> A10(mat,k,0,1,k);
|
Block<MatrixType,1,Dynamic> A10(mat,k,0,1,k);
|
||||||
Block<MatrixType,Dynamic,Dynamic> A20(mat,k+1,0,rs,k);
|
Block<MatrixType,Dynamic,Dynamic> A20(mat,k+1,0,rs,k);
|
||||||
|
|
||||||
RealScalar x = numext::real(mat.coeff(k, k));
|
RealScalar x = real(mat.coeff(k,k));
|
||||||
if (k>0) x -= A10.squaredNorm();
|
if (k>0) x -= A10.squaredNorm();
|
||||||
if (x <= RealScalar(0)) return k;
|
if (x<=RealScalar(0))
|
||||||
|
return k;
|
||||||
mat.coeffRef(k,k) = x = sqrt(x);
|
mat.coeffRef(k,k) = x = sqrt(x);
|
||||||
if (k>0 && rs>0) A21.noalias() -= A20 * A10.adjoint();
|
if (k>0 && rs>0) A21.noalias() -= A20 * A10.adjoint();
|
||||||
if (rs > 0) A21 /= x;
|
if (rs>0) A21 *= RealScalar(1)/x;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename MatrixType>
|
template<typename MatrixType>
|
||||||
static Index blocked(MatrixType& m) {
|
static typename MatrixType::Index blocked(MatrixType& m)
|
||||||
|
{
|
||||||
|
typedef typename MatrixType::Index Index;
|
||||||
eigen_assert(m.rows()==m.cols());
|
eigen_assert(m.rows()==m.cols());
|
||||||
Index size = m.rows();
|
Index size = m.rows();
|
||||||
if (size < 32) return unblocked(m);
|
if(size<32)
|
||||||
|
return unblocked(m);
|
||||||
|
|
||||||
Index blockSize = size/8;
|
Index blockSize = size/8;
|
||||||
blockSize = (blockSize/16)*16;
|
blockSize = (blockSize/16)*16;
|
||||||
blockSize = (std::min)((std::max)(blockSize,Index(8)), Index(128));
|
blockSize = (std::min)((std::max)(blockSize,Index(8)), Index(128));
|
||||||
|
|
||||||
for (Index k = 0; k < size; k += blockSize) {
|
for (Index k=0; k<size; k+=blockSize)
|
||||||
|
{
|
||||||
// partition the matrix:
|
// partition the matrix:
|
||||||
// A00 | - | -
|
// A00 | - | -
|
||||||
// lu = A10 | A11 | -
|
// lu = A10 | A11 | -
|
||||||
@@ -331,92 +250,62 @@ struct llt_inplace<Scalar, Lower> {
|
|||||||
Index ret;
|
Index ret;
|
||||||
if((ret=unblocked(A11))>=0) return k+ret;
|
if((ret=unblocked(A11))>=0) return k+ret;
|
||||||
if(rs>0) A11.adjoint().template triangularView<Upper>().template solveInPlace<OnTheRight>(A21);
|
if(rs>0) A11.adjoint().template triangularView<Upper>().template solveInPlace<OnTheRight>(A21);
|
||||||
if (rs > 0)
|
if(rs>0) A22.template selfadjointView<Lower>().rankUpdate(A21,-1); // bottleneck
|
||||||
A22.template selfadjointView<Lower>().rankUpdate(A21,
|
|
||||||
typename NumTraits<RealScalar>::Literal(-1)); // bottleneck
|
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <typename MatrixType, typename VectorType>
|
template<> struct llt_inplace<Upper>
|
||||||
static Index rankUpdate(MatrixType& mat, const VectorType& vec, const RealScalar& sigma) {
|
{
|
||||||
return Eigen::internal::llt_rank_update_lower(mat, vec, sigma);
|
template<typename MatrixType>
|
||||||
|
static EIGEN_STRONG_INLINE typename MatrixType::Index unblocked(MatrixType& mat)
|
||||||
|
{
|
||||||
|
Transpose<MatrixType> matt(mat);
|
||||||
|
return llt_inplace<Lower>::unblocked(matt);
|
||||||
|
}
|
||||||
|
template<typename MatrixType>
|
||||||
|
static EIGEN_STRONG_INLINE typename MatrixType::Index blocked(MatrixType& mat)
|
||||||
|
{
|
||||||
|
Transpose<MatrixType> matt(mat);
|
||||||
|
return llt_inplace<Lower>::blocked(matt);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Scalar>
|
template<typename MatrixType> struct LLT_Traits<MatrixType,Lower>
|
||||||
struct llt_inplace<Scalar, Upper> {
|
{
|
||||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
|
||||||
|
|
||||||
template <typename MatrixType>
|
|
||||||
static EIGEN_STRONG_INLINE Index unblocked(MatrixType& mat) {
|
|
||||||
Transpose<MatrixType> matt(mat);
|
|
||||||
return llt_inplace<Scalar, Lower>::unblocked(matt);
|
|
||||||
}
|
|
||||||
template <typename MatrixType>
|
|
||||||
static EIGEN_STRONG_INLINE Index blocked(MatrixType& mat) {
|
|
||||||
Transpose<MatrixType> matt(mat);
|
|
||||||
return llt_inplace<Scalar, Lower>::blocked(matt);
|
|
||||||
}
|
|
||||||
template <typename MatrixType, typename VectorType>
|
|
||||||
static Index rankUpdate(MatrixType& mat, const VectorType& vec, const RealScalar& sigma) {
|
|
||||||
Transpose<MatrixType> matt(mat);
|
|
||||||
return llt_inplace<Scalar, Lower>::rankUpdate(matt, vec.conjugate(), sigma);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename MatrixType>
|
|
||||||
struct LLT_Traits<MatrixType, Lower> {
|
|
||||||
typedef const TriangularView<const MatrixType, Lower> MatrixL;
|
typedef const TriangularView<const MatrixType, Lower> MatrixL;
|
||||||
typedef const TriangularView<const typename MatrixType::AdjointReturnType, Upper> MatrixU;
|
typedef const TriangularView<const typename MatrixType::AdjointReturnType, Upper> MatrixU;
|
||||||
static inline MatrixL getL(const MatrixType& m) { return MatrixL(m); }
|
inline static MatrixL getL(const MatrixType& m) { return m; }
|
||||||
static inline MatrixU getU(const MatrixType& m) { return MatrixU(m.adjoint()); }
|
inline static MatrixU getU(const MatrixType& m) { return m.adjoint(); }
|
||||||
static bool inplace_decomposition(MatrixType& m) {
|
static bool inplace_decomposition(MatrixType& m)
|
||||||
return llt_inplace<typename MatrixType::Scalar, Lower>::blocked(m) == -1;
|
{ return llt_inplace<Lower>::blocked(m)==-1; }
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename MatrixType>
|
template<typename MatrixType> struct LLT_Traits<MatrixType,Upper>
|
||||||
struct LLT_Traits<MatrixType, Upper> {
|
{
|
||||||
typedef const TriangularView<const typename MatrixType::AdjointReturnType, Lower> MatrixL;
|
typedef const TriangularView<const typename MatrixType::AdjointReturnType, Lower> MatrixL;
|
||||||
typedef const TriangularView<const MatrixType, Upper> MatrixU;
|
typedef const TriangularView<const MatrixType, Upper> MatrixU;
|
||||||
static inline MatrixL getL(const MatrixType& m) { return MatrixL(m.adjoint()); }
|
inline static MatrixL getL(const MatrixType& m) { return m.adjoint(); }
|
||||||
static inline MatrixU getU(const MatrixType& m) { return MatrixU(m); }
|
inline static MatrixU getU(const MatrixType& m) { return m; }
|
||||||
static bool inplace_decomposition(MatrixType& m) {
|
static bool inplace_decomposition(MatrixType& m)
|
||||||
return llt_inplace<typename MatrixType::Scalar, Upper>::blocked(m) == -1;
|
{ return llt_inplace<Upper>::blocked(m)==-1; }
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
/** Computes / recomputes the Cholesky decomposition A = LL^* = U^*U of \a matrix
|
/** Computes / recomputes the Cholesky decomposition A = LL^* = U^*U of \a matrix
|
||||||
*
|
*
|
||||||
* \returns a reference to *this
|
|
||||||
*
|
*
|
||||||
* Example: \include TutorialLinAlgComputeTwice.cpp
|
* \returns a reference to *this
|
||||||
* Output: \verbinclude TutorialLinAlgComputeTwice.out
|
|
||||||
*/
|
*/
|
||||||
template <typename MatrixType, int UpLo_>
|
template<typename MatrixType, int _UpLo>
|
||||||
template <typename InputType>
|
LLT<MatrixType,_UpLo>& LLT<MatrixType,_UpLo>::compute(const MatrixType& a)
|
||||||
LLT<MatrixType, UpLo_>& LLT<MatrixType, UpLo_>::compute(const EigenBase<InputType>& a) {
|
{
|
||||||
eigen_assert(a.rows() == a.cols());
|
assert(a.rows()==a.cols());
|
||||||
const Index size = a.rows();
|
const Index size = a.rows();
|
||||||
m_matrix.resize(size, size);
|
m_matrix.resize(size, size);
|
||||||
if (!internal::is_same_dense(m_matrix, a.derived())) m_matrix = a.derived();
|
m_matrix = a;
|
||||||
|
|
||||||
// Compute matrix L1 norm = max abs column sum.
|
|
||||||
m_l1_norm = RealScalar(0);
|
|
||||||
// TODO: move this code to SelfAdjointView
|
|
||||||
for (Index col = 0; col < size; ++col) {
|
|
||||||
RealScalar abs_col_sum;
|
|
||||||
if (UpLo_ == Lower)
|
|
||||||
abs_col_sum =
|
|
||||||
m_matrix.col(col).tail(size - col).template lpNorm<1>() + m_matrix.row(col).head(col).template lpNorm<1>();
|
|
||||||
else
|
|
||||||
abs_col_sum =
|
|
||||||
m_matrix.col(col).head(col).template lpNorm<1>() + m_matrix.row(col).tail(size - col).template lpNorm<1>();
|
|
||||||
if (abs_col_sum > m_l1_norm) m_l1_norm = abs_col_sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_isInitialized = true;
|
m_isInitialized = true;
|
||||||
bool ok = Traits::inplace_decomposition(m_matrix);
|
bool ok = Traits::inplace_decomposition(m_matrix);
|
||||||
@@ -425,58 +314,39 @@ LLT<MatrixType, UpLo_>& LLT<MatrixType, UpLo_>::compute(const EigenBase<InputTyp
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Performs a rank one update (or dowdate) of the current decomposition.
|
namespace internal {
|
||||||
* If A = LL^* before the rank one update,
|
template<typename _MatrixType, int UpLo, typename Rhs>
|
||||||
* then after it we have LL^* = A + sigma * v v^* where \a v must be a vector
|
struct solve_retval<LLT<_MatrixType, UpLo>, Rhs>
|
||||||
* of same dimension.
|
: solve_retval_base<LLT<_MatrixType, UpLo>, Rhs>
|
||||||
*/
|
{
|
||||||
template <typename MatrixType_, int UpLo_>
|
typedef LLT<_MatrixType,UpLo> LLTType;
|
||||||
template <typename VectorType>
|
EIGEN_MAKE_SOLVE_HELPERS(LLTType,Rhs)
|
||||||
LLT<MatrixType_, UpLo_>& LLT<MatrixType_, UpLo_>::rankUpdate(const VectorType& v, const RealScalar& sigma) {
|
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorType);
|
|
||||||
eigen_assert(v.size() == m_matrix.cols());
|
|
||||||
eigen_assert(m_isInitialized);
|
|
||||||
if (internal::llt_inplace<typename MatrixType::Scalar, UpLo>::rankUpdate(m_matrix, v, sigma) >= 0)
|
|
||||||
m_info = NumericalIssue;
|
|
||||||
else
|
|
||||||
m_info = Success;
|
|
||||||
|
|
||||||
return *this;
|
template<typename Dest> void evalTo(Dest& dst) const
|
||||||
|
{
|
||||||
|
dst = rhs();
|
||||||
|
dec().solveInPlace(dst);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
template <typename MatrixType_, int UpLo_>
|
|
||||||
template <typename RhsType, typename DstType>
|
|
||||||
void LLT<MatrixType_, UpLo_>::_solve_impl(const RhsType& rhs, DstType& dst) const {
|
|
||||||
_solve_impl_transposed<true>(rhs, 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
|
|
||||||
|
|
||||||
/** \internal use x = llt_object.solve(x);
|
/** \internal use x = llt_object.solve(x);
|
||||||
*
|
*
|
||||||
* This is the \em in-place version of solve().
|
* This is the \em in-place version of solve().
|
||||||
*
|
*
|
||||||
* \param bAndX represents both the right-hand side matrix b and result x.
|
* \param bAndX represents both the right-hand side matrix b and result x.
|
||||||
*
|
*
|
||||||
* This version avoids a copy when the right hand side matrix b is not needed anymore.
|
* \returns true always! If you need to check for existence of solutions, use another decomposition like LU, QR, or SVD.
|
||||||
*
|
*
|
||||||
* \warning The parameter is only marked 'const' to make the C++ compiler accept a temporary expression here.
|
* This version avoids a copy when the right hand side matrix b is not
|
||||||
* This function will const_cast it, so constness isn't honored here.
|
* needed anymore.
|
||||||
*
|
*
|
||||||
* \sa LLT::solve(), MatrixBase::llt()
|
* \sa LLT::solve(), MatrixBase::llt()
|
||||||
*/
|
*/
|
||||||
template <typename MatrixType, int UpLo_>
|
template<typename MatrixType, int _UpLo>
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
void LLT<MatrixType, UpLo_>::solveInPlace(const MatrixBase<Derived>& bAndX) const {
|
void LLT<MatrixType,_UpLo>::solveInPlace(MatrixBase<Derived> &bAndX) const
|
||||||
|
{
|
||||||
eigen_assert(m_isInitialized && "LLT is not initialized.");
|
eigen_assert(m_isInitialized && "LLT is not initialized.");
|
||||||
eigen_assert(m_matrix.rows()==bAndX.rows());
|
eigen_assert(m_matrix.rows()==bAndX.rows());
|
||||||
matrixL().solveInPlace(bAndX);
|
matrixL().solveInPlace(bAndX);
|
||||||
@@ -486,31 +356,31 @@ void LLT<MatrixType, UpLo_>::solveInPlace(const MatrixBase<Derived>& bAndX) cons
|
|||||||
/** \returns the matrix represented by the decomposition,
|
/** \returns the matrix represented by the decomposition,
|
||||||
* i.e., it returns the product: L L^*.
|
* i.e., it returns the product: L L^*.
|
||||||
* This function is provided for debug purpose. */
|
* This function is provided for debug purpose. */
|
||||||
template <typename MatrixType, int UpLo_>
|
template<typename MatrixType, int _UpLo>
|
||||||
MatrixType LLT<MatrixType, UpLo_>::reconstructedMatrix() const {
|
MatrixType LLT<MatrixType,_UpLo>::reconstructedMatrix() const
|
||||||
|
{
|
||||||
eigen_assert(m_isInitialized && "LLT is not initialized.");
|
eigen_assert(m_isInitialized && "LLT is not initialized.");
|
||||||
return matrixL() * matrixL().adjoint().toDenseMatrix();
|
return matrixL() * matrixL().adjoint().toDenseMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \cholesky_module
|
/** \cholesky_module
|
||||||
* \returns the LLT decomposition of \c *this
|
* \returns the LLT decomposition of \c *this
|
||||||
* \sa SelfAdjointView::llt()
|
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline LLT<typename MatrixBase<Derived>::PlainObject> MatrixBase<Derived>::llt() const {
|
inline const LLT<typename MatrixBase<Derived>::PlainObject>
|
||||||
|
MatrixBase<Derived>::llt() const
|
||||||
|
{
|
||||||
return LLT<PlainObject>(derived());
|
return LLT<PlainObject>(derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \cholesky_module
|
/** \cholesky_module
|
||||||
* \returns the LLT decomposition of \c *this
|
* \returns the LLT decomposition of \c *this
|
||||||
* \sa SelfAdjointView::llt()
|
|
||||||
*/
|
*/
|
||||||
template<typename MatrixType, unsigned int UpLo>
|
template<typename MatrixType, unsigned int UpLo>
|
||||||
inline LLT<typename SelfAdjointView<MatrixType, UpLo>::PlainObject, UpLo> SelfAdjointView<MatrixType, UpLo>::llt()
|
inline const LLT<typename SelfAdjointView<MatrixType, UpLo>::PlainObject, UpLo>
|
||||||
const {
|
SelfAdjointView<MatrixType, UpLo>::llt() const
|
||||||
|
{
|
||||||
return LLT<PlainObject,UpLo>(m_matrix);
|
return LLT<PlainObject,UpLo>(m_matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_LLT_H
|
#endif // EIGEN_LLT_H
|
||||||
|
|||||||
@@ -1,124 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011, Intel Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
* Neither the name of Intel Corporation nor the names of its contributors may
|
|
||||||
be used to endorse or promote products derived from this software without
|
|
||||||
specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
********************************************************************************
|
|
||||||
* Content : Eigen bindings to LAPACKe
|
|
||||||
* LLt decomposition based on LAPACKE_?potrf function.
|
|
||||||
********************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef EIGEN_LLT_LAPACKE_H
|
|
||||||
#define EIGEN_LLT_LAPACKE_H
|
|
||||||
|
|
||||||
// IWYU pragma: private
|
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
namespace lapacke_helpers {
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------
|
|
||||||
// Dispatch for rank update handling upper and lower parts
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template <UpLoType Mode>
|
|
||||||
struct rank_update {};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct rank_update<Lower> {
|
|
||||||
template <typename MatrixType, typename VectorType>
|
|
||||||
static Index run(MatrixType &mat, const VectorType &vec, const typename MatrixType::RealScalar &sigma) {
|
|
||||||
return Eigen::internal::llt_rank_update_lower(mat, vec, sigma);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct rank_update<Upper> {
|
|
||||||
template <typename MatrixType, typename VectorType>
|
|
||||||
static Index run(MatrixType &mat, const VectorType &vec, const typename MatrixType::RealScalar &sigma) {
|
|
||||||
Transpose<MatrixType> matt(mat);
|
|
||||||
return Eigen::internal::llt_rank_update_lower(matt, vec.conjugate(), sigma);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------
|
|
||||||
// Generic lapacke llt implementation that hands of to the dispatches
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template <typename Scalar, UpLoType Mode>
|
|
||||||
struct lapacke_llt {
|
|
||||||
EIGEN_STATIC_ASSERT(((Mode == Lower) || (Mode == Upper)), MODE_MUST_BE_UPPER_OR_LOWER)
|
|
||||||
template <typename MatrixType>
|
|
||||||
static Index blocked(MatrixType &m) {
|
|
||||||
eigen_assert(m.rows() == m.cols());
|
|
||||||
if (m.rows() == 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
/* Set up parameters for ?potrf */
|
|
||||||
lapack_int size = to_lapack(m.rows());
|
|
||||||
lapack_int matrix_order = lapack_storage_of(m);
|
|
||||||
constexpr char uplo = Mode == Upper ? 'U' : 'L';
|
|
||||||
Scalar *a = &(m.coeffRef(0, 0));
|
|
||||||
lapack_int lda = to_lapack(m.outerStride());
|
|
||||||
|
|
||||||
lapack_int info = potrf(matrix_order, uplo, size, to_lapack(a), lda);
|
|
||||||
info = (info == 0) ? -1 : info > 0 ? info - 1 : size;
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename MatrixType, typename VectorType>
|
|
||||||
static Index rankUpdate(MatrixType &mat, const VectorType &vec, const typename MatrixType::RealScalar &sigma) {
|
|
||||||
return rank_update<Mode>::run(mat, vec, sigma);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace lapacke_helpers
|
|
||||||
// end namespace lapacke_helpers
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Here, we just put the generic implementation from lapacke_llt into a full specialization of the llt_inplace
|
|
||||||
* type. By being a full specialization, the versions defined here thus get precedence over the generic implementation
|
|
||||||
* in LLT.h for double, float and complex double, complex float types.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define EIGEN_LAPACKE_LLT(EIGTYPE) \
|
|
||||||
template <> \
|
|
||||||
struct llt_inplace<EIGTYPE, Lower> : public lapacke_helpers::lapacke_llt<EIGTYPE, Lower> {}; \
|
|
||||||
template <> \
|
|
||||||
struct llt_inplace<EIGTYPE, Upper> : public lapacke_helpers::lapacke_llt<EIGTYPE, Upper> {};
|
|
||||||
|
|
||||||
EIGEN_LAPACKE_LLT(double)
|
|
||||||
EIGEN_LAPACKE_LLT(float)
|
|
||||||
EIGEN_LAPACKE_LLT(std::complex<double>)
|
|
||||||
EIGEN_LAPACKE_LLT(std::complex<float>)
|
|
||||||
|
|
||||||
#undef EIGEN_LAPACKE_LLT
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_LLT_LAPACKE_H
|
|
||||||
@@ -1,738 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
|
|
||||||
//
|
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
#ifndef EIGEN_CHOLMODSUPPORT_H
|
|
||||||
#define EIGEN_CHOLMODSUPPORT_H
|
|
||||||
|
|
||||||
// IWYU pragma: private
|
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template <typename Scalar>
|
|
||||||
struct cholmod_configure_matrix;
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct cholmod_configure_matrix<double> {
|
|
||||||
template <typename CholmodType>
|
|
||||||
static void run(CholmodType& mat) {
|
|
||||||
mat.xtype = CHOLMOD_REAL;
|
|
||||||
mat.dtype = CHOLMOD_DOUBLE;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct cholmod_configure_matrix<std::complex<double> > {
|
|
||||||
template <typename CholmodType>
|
|
||||||
static void run(CholmodType& mat) {
|
|
||||||
mat.xtype = CHOLMOD_COMPLEX;
|
|
||||||
mat.dtype = CHOLMOD_DOUBLE;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Other scalar types are not yet supported by Cholmod
|
|
||||||
// template<> struct cholmod_configure_matrix<float> {
|
|
||||||
// template<typename CholmodType>
|
|
||||||
// static void run(CholmodType& mat) {
|
|
||||||
// mat.xtype = CHOLMOD_REAL;
|
|
||||||
// mat.dtype = CHOLMOD_SINGLE;
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// template<> struct cholmod_configure_matrix<std::complex<float> > {
|
|
||||||
// template<typename CholmodType>
|
|
||||||
// static void run(CholmodType& mat) {
|
|
||||||
// mat.xtype = CHOLMOD_COMPLEX;
|
|
||||||
// mat.dtype = CHOLMOD_SINGLE;
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
/** Wraps the Eigen sparse matrix \a mat into a Cholmod sparse matrix object.
|
|
||||||
* Note that the data are shared.
|
|
||||||
*/
|
|
||||||
template <typename Scalar_, int Options_, typename StorageIndex_>
|
|
||||||
cholmod_sparse viewAsCholmod(Ref<SparseMatrix<Scalar_, Options_, StorageIndex_> > mat) {
|
|
||||||
cholmod_sparse res;
|
|
||||||
res.nzmax = mat.nonZeros();
|
|
||||||
res.nrow = mat.rows();
|
|
||||||
res.ncol = mat.cols();
|
|
||||||
res.p = mat.outerIndexPtr();
|
|
||||||
res.i = mat.innerIndexPtr();
|
|
||||||
res.x = mat.valuePtr();
|
|
||||||
res.z = 0;
|
|
||||||
res.sorted = 1;
|
|
||||||
if (mat.isCompressed()) {
|
|
||||||
res.packed = 1;
|
|
||||||
res.nz = 0;
|
|
||||||
} else {
|
|
||||||
res.packed = 0;
|
|
||||||
res.nz = mat.innerNonZeroPtr();
|
|
||||||
}
|
|
||||||
|
|
||||||
res.dtype = 0;
|
|
||||||
res.stype = -1;
|
|
||||||
|
|
||||||
if (internal::is_same<StorageIndex_, int>::value) {
|
|
||||||
res.itype = CHOLMOD_INT;
|
|
||||||
} else if (internal::is_same<StorageIndex_, SuiteSparse_long>::value) {
|
|
||||||
res.itype = CHOLMOD_LONG;
|
|
||||||
} else {
|
|
||||||
eigen_assert(false && "Index type not supported yet");
|
|
||||||
}
|
|
||||||
|
|
||||||
// setup res.xtype
|
|
||||||
internal::cholmod_configure_matrix<Scalar_>::run(res);
|
|
||||||
|
|
||||||
res.stype = 0;
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Scalar_, int Options_, typename Index_>
|
|
||||||
const cholmod_sparse viewAsCholmod(const SparseMatrix<Scalar_, Options_, Index_>& mat) {
|
|
||||||
cholmod_sparse res = viewAsCholmod(Ref<SparseMatrix<Scalar_, Options_, Index_> >(mat.const_cast_derived()));
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Scalar_, int Options_, typename Index_>
|
|
||||||
const cholmod_sparse viewAsCholmod(const SparseVector<Scalar_, Options_, Index_>& mat) {
|
|
||||||
cholmod_sparse res = viewAsCholmod(Ref<SparseMatrix<Scalar_, Options_, Index_> >(mat.const_cast_derived()));
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns a view of the Eigen sparse matrix \a mat as Cholmod sparse matrix.
|
|
||||||
* The data are not copied but shared. */
|
|
||||||
template <typename Scalar_, int Options_, typename Index_, unsigned int UpLo>
|
|
||||||
cholmod_sparse viewAsCholmod(const SparseSelfAdjointView<const SparseMatrix<Scalar_, Options_, Index_>, UpLo>& mat) {
|
|
||||||
cholmod_sparse res = viewAsCholmod(Ref<SparseMatrix<Scalar_, Options_, Index_> >(mat.matrix().const_cast_derived()));
|
|
||||||
|
|
||||||
if (UpLo == Upper) 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns a view of the Eigen \b dense matrix \a mat as Cholmod dense matrix.
|
|
||||||
* The data are not copied but shared. */
|
|
||||||
template <typename Derived>
|
|
||||||
cholmod_dense viewAsCholmod(MatrixBase<Derived>& mat) {
|
|
||||||
EIGEN_STATIC_ASSERT((internal::traits<Derived>::Flags & RowMajorBit) == 0,
|
|
||||||
THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
|
|
||||||
typedef typename Derived::Scalar Scalar;
|
|
||||||
|
|
||||||
cholmod_dense res;
|
|
||||||
res.nrow = mat.rows();
|
|
||||||
res.ncol = mat.cols();
|
|
||||||
res.nzmax = res.nrow * res.ncol;
|
|
||||||
res.d = Derived::IsVectorAtCompileTime ? mat.derived().size() : mat.derived().outerStride();
|
|
||||||
res.x = (void*)(mat.derived().data());
|
|
||||||
res.z = 0;
|
|
||||||
|
|
||||||
internal::cholmod_configure_matrix<Scalar>::run(res);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns a view of the Cholmod sparse matrix \a cm as an Eigen sparse matrix.
|
|
||||||
* The data are not copied but shared. */
|
|
||||||
template <typename Scalar, typename StorageIndex>
|
|
||||||
Map<const SparseMatrix<Scalar, ColMajor, StorageIndex> > viewAsEigen(cholmod_sparse& cm) {
|
|
||||||
return Map<const SparseMatrix<Scalar, ColMajor, StorageIndex> >(
|
|
||||||
cm.nrow, cm.ncol, static_cast<StorageIndex*>(cm.p)[cm.ncol], static_cast<StorageIndex*>(cm.p),
|
|
||||||
static_cast<StorageIndex*>(cm.i), static_cast<Scalar*>(cm.x));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns a view of the Cholmod sparse matrix factor \a cm as an Eigen sparse matrix.
|
|
||||||
* The data are not copied but shared. */
|
|
||||||
template <typename Scalar, typename StorageIndex>
|
|
||||||
Map<const SparseMatrix<Scalar, ColMajor, StorageIndex> > viewAsEigen(cholmod_factor& cm) {
|
|
||||||
return Map<const SparseMatrix<Scalar, ColMajor, StorageIndex> >(
|
|
||||||
cm.n, cm.n, static_cast<StorageIndex*>(cm.p)[cm.n], 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)
|
|
||||||
EIGEN_CHOLMOD_SPECIALIZE1(cholmod_sparse*, factor_to_sparse, cholmod_factor, L)
|
|
||||||
|
|
||||||
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 { CholmodAuto, CholmodSimplicialLLt, CholmodSupernodalLLt, CholmodLDLt };
|
|
||||||
|
|
||||||
/** \ingroup CholmodSupport_Module
|
|
||||||
* \class CholmodBase
|
|
||||||
* \brief The base class for the direct Cholesky factorization of Cholmod
|
|
||||||
* \sa class CholmodSupernodalLLT, class CholmodSimplicialLDLT, class CholmodSimplicialLLT
|
|
||||||
*/
|
|
||||||
template <typename MatrixType_, int UpLo_, typename Derived>
|
|
||||||
class CholmodBase : public SparseSolverBase<Derived> {
|
|
||||||
protected:
|
|
||||||
typedef SparseSolverBase<Derived> Base;
|
|
||||||
using Base::derived;
|
|
||||||
using Base::m_isInitialized;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef MatrixType_ MatrixType;
|
|
||||||
enum { UpLo = UpLo_ };
|
|
||||||
typedef typename MatrixType::Scalar Scalar;
|
|
||||||
typedef typename MatrixType::RealScalar RealScalar;
|
|
||||||
typedef MatrixType CholMatrixType;
|
|
||||||
typedef typename MatrixType::StorageIndex StorageIndex;
|
|
||||||
enum { ColsAtCompileTime = MatrixType::ColsAtCompileTime, MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime };
|
|
||||||
|
|
||||||
public:
|
|
||||||
CholmodBase() : m_cholmodFactor(0), m_info(Success), m_factorizationIsOk(false), m_analysisIsOk(false) {
|
|
||||||
EIGEN_STATIC_ASSERT((internal::is_same<double, RealScalar>::value), CHOLMOD_SUPPORTS_DOUBLE_PRECISION_ONLY);
|
|
||||||
m_shiftOffset[0] = m_shiftOffset[1] = 0.0;
|
|
||||||
internal::cm_start<StorageIndex>(m_cholmod);
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit CholmodBase(const MatrixType& matrix)
|
|
||||||
: m_cholmodFactor(0), m_info(Success), m_factorizationIsOk(false), m_analysisIsOk(false) {
|
|
||||||
EIGEN_STATIC_ASSERT((internal::is_same<double, RealScalar>::value), CHOLMOD_SUPPORTS_DOUBLE_PRECISION_ONLY);
|
|
||||||
m_shiftOffset[0] = m_shiftOffset[1] = 0.0;
|
|
||||||
internal::cm_start<StorageIndex>(m_cholmod);
|
|
||||||
compute(matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
~CholmodBase() {
|
|
||||||
if (m_cholmodFactor) internal::cm_free_factor<StorageIndex>(m_cholmodFactor, m_cholmod);
|
|
||||||
internal::cm_finish<StorageIndex>(m_cholmod);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline StorageIndex cols() const { return internal::convert_index<StorageIndex, Index>(m_cholmodFactor->n); }
|
|
||||||
inline StorageIndex rows() const { return internal::convert_index<StorageIndex, Index>(m_cholmodFactor->n); }
|
|
||||||
|
|
||||||
/** \brief Reports whether previous computation was successful.
|
|
||||||
*
|
|
||||||
* \returns \c Success if computation was successful,
|
|
||||||
* \c NumericalIssue if the matrix.appears to be negative.
|
|
||||||
*/
|
|
||||||
ComputationInfo info() const {
|
|
||||||
eigen_assert(m_isInitialized && "Decomposition is not initialized.");
|
|
||||||
return m_info;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Computes the sparse Cholesky decomposition of \a matrix */
|
|
||||||
Derived& compute(const MatrixType& matrix) {
|
|
||||||
analyzePattern(matrix);
|
|
||||||
factorize(matrix);
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Performs a symbolic decomposition on the sparsity pattern of \a matrix.
|
|
||||||
*
|
|
||||||
* This function is particularly useful when solving for several problems having the same structure.
|
|
||||||
*
|
|
||||||
* \sa factorize()
|
|
||||||
*/
|
|
||||||
void analyzePattern(const MatrixType& matrix) {
|
|
||||||
if (m_cholmodFactor) {
|
|
||||||
internal::cm_free_factor<StorageIndex>(m_cholmodFactor, m_cholmod);
|
|
||||||
m_cholmodFactor = 0;
|
|
||||||
}
|
|
||||||
cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView<UpLo>());
|
|
||||||
m_cholmodFactor = internal::cm_analyze<StorageIndex>(A, m_cholmod);
|
|
||||||
|
|
||||||
this->m_isInitialized = true;
|
|
||||||
this->m_info = Success;
|
|
||||||
m_analysisIsOk = true;
|
|
||||||
m_factorizationIsOk = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Performs a numeric decomposition of \a matrix
|
|
||||||
*
|
|
||||||
* The given matrix must have the same sparsity pattern as the matrix on which the symbolic decomposition has been
|
|
||||||
* performed.
|
|
||||||
*
|
|
||||||
* \sa analyzePattern()
|
|
||||||
*/
|
|
||||||
void factorize(const MatrixType& matrix) {
|
|
||||||
eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
|
|
||||||
cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView<UpLo>());
|
|
||||||
internal::cm_factorize_p<StorageIndex>(&A, m_shiftOffset, 0, 0, m_cholmodFactor, m_cholmod);
|
|
||||||
|
|
||||||
// If the factorization failed, either the input matrix was zero (so m_cholmodFactor == nullptr), or minor is the
|
|
||||||
// column at which it failed. On success minor == n.
|
|
||||||
this->m_info =
|
|
||||||
(m_cholmodFactor != nullptr && m_cholmodFactor->minor == m_cholmodFactor->n ? Success : NumericalIssue);
|
|
||||||
m_factorizationIsOk = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns a reference to the Cholmod's configuration structure to get a full control over the performed operations.
|
|
||||||
* See the Cholmod user guide for details. */
|
|
||||||
cholmod_common& cholmod() { return m_cholmod; }
|
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
/** \internal */
|
|
||||||
template <typename Rhs, typename Dest>
|
|
||||||
void _solve_impl(const MatrixBase<Rhs>& b, MatrixBase<Dest>& dest) const {
|
|
||||||
eigen_assert(m_factorizationIsOk &&
|
|
||||||
"The decomposition is not in a valid state for solving, you must first call either compute() or "
|
|
||||||
"symbolic()/numeric()");
|
|
||||||
const Index size = m_cholmodFactor->n;
|
|
||||||
EIGEN_UNUSED_VARIABLE(size);
|
|
||||||
eigen_assert(size == b.rows());
|
|
||||||
|
|
||||||
// Cholmod needs column-major storage without inner-stride, which corresponds to the default behavior of Ref.
|
|
||||||
Ref<const Matrix<typename Rhs::Scalar, Dynamic, Dynamic, ColMajor> > b_ref(b.derived());
|
|
||||||
|
|
||||||
cholmod_dense b_cd = viewAsCholmod(b_ref);
|
|
||||||
cholmod_dense* x_cd = internal::cm_solve<StorageIndex>(CHOLMOD_A, *m_cholmodFactor, b_cd, m_cholmod);
|
|
||||||
if (!x_cd) {
|
|
||||||
this->m_info = NumericalIssue;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 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());
|
|
||||||
internal::cm_free_dense<StorageIndex>(x_cd, m_cholmod);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal */
|
|
||||||
template <typename RhsDerived, typename DestDerived>
|
|
||||||
void _solve_impl(const SparseMatrixBase<RhsDerived>& b, SparseMatrixBase<DestDerived>& dest) const {
|
|
||||||
eigen_assert(m_factorizationIsOk &&
|
|
||||||
"The decomposition is not in a valid state for solving, you must first call either compute() or "
|
|
||||||
"symbolic()/numeric()");
|
|
||||||
const Index size = m_cholmodFactor->n;
|
|
||||||
EIGEN_UNUSED_VARIABLE(size);
|
|
||||||
eigen_assert(size == b.rows());
|
|
||||||
|
|
||||||
// note: cs stands for Cholmod Sparse
|
|
||||||
Ref<SparseMatrix<typename RhsDerived::Scalar, ColMajor, typename RhsDerived::StorageIndex> > b_ref(
|
|
||||||
b.const_cast_derived());
|
|
||||||
cholmod_sparse b_cs = viewAsCholmod(b_ref);
|
|
||||||
cholmod_sparse* x_cs = internal::cm_spsolve<StorageIndex>(CHOLMOD_A, *m_cholmodFactor, b_cs, m_cholmod);
|
|
||||||
if (!x_cs) {
|
|
||||||
this->m_info = NumericalIssue;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 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, typename DestDerived::StorageIndex>(*x_cs);
|
|
||||||
internal::cm_free_sparse<StorageIndex>(x_cs, m_cholmod);
|
|
||||||
}
|
|
||||||
#endif // EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
|
|
||||||
/** Sets the shift parameter that will be used to adjust the diagonal coefficients during the numerical factorization.
|
|
||||||
*
|
|
||||||
* During the numerical factorization, an offset term is added to the diagonal coefficients:\n
|
|
||||||
* \c d_ii = \a offset + \c d_ii
|
|
||||||
*
|
|
||||||
* The default is \a offset=0.
|
|
||||||
*
|
|
||||||
* \returns a reference to \c *this.
|
|
||||||
*/
|
|
||||||
Derived& setShift(const RealScalar& offset) {
|
|
||||||
m_shiftOffset[0] = double(offset);
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \returns the determinant of the underlying matrix from the current factorization */
|
|
||||||
Scalar determinant() const {
|
|
||||||
using std::exp;
|
|
||||||
return exp(logDeterminant());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \returns the log determinant of the underlying matrix from the current factorization */
|
|
||||||
Scalar logDeterminant() const {
|
|
||||||
using numext::real;
|
|
||||||
using std::log;
|
|
||||||
eigen_assert(m_factorizationIsOk &&
|
|
||||||
"The decomposition is not in a valid state for solving, you must first call either compute() or "
|
|
||||||
"symbolic()/numeric()");
|
|
||||||
|
|
||||||
RealScalar logDet = 0;
|
|
||||||
Scalar* x = static_cast<Scalar*>(m_cholmodFactor->x);
|
|
||||||
if (m_cholmodFactor->is_super) {
|
|
||||||
// Supernodal factorization stored as a packed list of dense column-major blocks,
|
|
||||||
// as described by the following structure:
|
|
||||||
|
|
||||||
// super[k] == index of the first column of the j-th super node
|
|
||||||
StorageIndex* super = static_cast<StorageIndex*>(m_cholmodFactor->super);
|
|
||||||
// pi[k] == offset to the description of row indices
|
|
||||||
StorageIndex* pi = static_cast<StorageIndex*>(m_cholmodFactor->pi);
|
|
||||||
// px[k] == offset to the respective dense block
|
|
||||||
StorageIndex* px = static_cast<StorageIndex*>(m_cholmodFactor->px);
|
|
||||||
|
|
||||||
Index nb_super_nodes = m_cholmodFactor->nsuper;
|
|
||||||
for (Index k = 0; k < nb_super_nodes; ++k) {
|
|
||||||
StorageIndex ncols = super[k + 1] - super[k];
|
|
||||||
StorageIndex nrows = pi[k + 1] - pi[k];
|
|
||||||
|
|
||||||
Map<const Array<Scalar, 1, Dynamic>, 0, InnerStride<> > sk(x + px[k], ncols, InnerStride<>(nrows + 1));
|
|
||||||
logDet += sk.real().log().sum();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Simplicial factorization stored as standard CSC matrix.
|
|
||||||
StorageIndex* p = static_cast<StorageIndex*>(m_cholmodFactor->p);
|
|
||||||
Index size = m_cholmodFactor->n;
|
|
||||||
for (Index k = 0; k < size; ++k) logDet += log(real(x[p[k]]));
|
|
||||||
}
|
|
||||||
if (m_cholmodFactor->is_ll) logDet *= 2.0;
|
|
||||||
return logDet;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
void dumpMemory(Stream& /*s*/) {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
mutable cholmod_common m_cholmod;
|
|
||||||
cholmod_factor* m_cholmodFactor;
|
|
||||||
double m_shiftOffset[2];
|
|
||||||
mutable ComputationInfo m_info;
|
|
||||||
int m_factorizationIsOk;
|
|
||||||
int m_analysisIsOk;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \ingroup CholmodSupport_Module
|
|
||||||
* \class CholmodSimplicialLLT
|
|
||||||
* \brief A simplicial direct Cholesky (LLT) factorization and solver based on Cholmod
|
|
||||||
*
|
|
||||||
* This class allows to solve for A.X = B sparse linear problems via a simplicial LL^T Cholesky factorization
|
|
||||||
* using the Cholmod library.
|
|
||||||
* This simplicial variant is equivalent to Eigen's built-in SimplicialLLT class. Therefore, it has little practical
|
|
||||||
* interest. The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices X and B can be
|
|
||||||
* either dense or sparse.
|
|
||||||
*
|
|
||||||
* \tparam MatrixType_ the type of the sparse matrix A, it must be a SparseMatrix<>
|
|
||||||
* \tparam UpLo_ the triangular part that will be used for the computations. It can be Lower
|
|
||||||
* or Upper. Default is Lower.
|
|
||||||
*
|
|
||||||
* \implsparsesolverconcept
|
|
||||||
*
|
|
||||||
* This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non
|
|
||||||
* compressed.
|
|
||||||
*
|
|
||||||
* \warning Only double precision real and complex scalar types are supported by Cholmod.
|
|
||||||
*
|
|
||||||
* \sa \ref TutorialSparseSolverConcept, class CholmodSupernodalLLT, class SimplicialLLT
|
|
||||||
*/
|
|
||||||
template <typename MatrixType_, int UpLo_ = Lower>
|
|
||||||
class CholmodSimplicialLLT : public CholmodBase<MatrixType_, UpLo_, CholmodSimplicialLLT<MatrixType_, UpLo_> > {
|
|
||||||
typedef CholmodBase<MatrixType_, UpLo_, CholmodSimplicialLLT> Base;
|
|
||||||
using Base::m_cholmod;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef MatrixType_ MatrixType;
|
|
||||||
typedef typename MatrixType::Scalar Scalar;
|
|
||||||
typedef typename MatrixType::RealScalar RealScalar;
|
|
||||||
typedef typename MatrixType::StorageIndex StorageIndex;
|
|
||||||
typedef TriangularView<const MatrixType, Eigen::Lower> MatrixL;
|
|
||||||
typedef TriangularView<const typename MatrixType::AdjointReturnType, Eigen::Upper> MatrixU;
|
|
||||||
|
|
||||||
CholmodSimplicialLLT() : Base() { init(); }
|
|
||||||
|
|
||||||
CholmodSimplicialLLT(const MatrixType& matrix) : Base() {
|
|
||||||
init();
|
|
||||||
this->compute(matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
~CholmodSimplicialLLT() {}
|
|
||||||
|
|
||||||
/** \returns an expression of the factor L */
|
|
||||||
inline MatrixL matrixL() const { return viewAsEigen<Scalar, StorageIndex>(*Base::m_cholmodFactor); }
|
|
||||||
|
|
||||||
/** \returns an expression of the factor U (= L^*) */
|
|
||||||
inline MatrixU matrixU() const { return matrixL().adjoint(); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void init() {
|
|
||||||
m_cholmod.final_asis = 0;
|
|
||||||
m_cholmod.supernodal = CHOLMOD_SIMPLICIAL;
|
|
||||||
m_cholmod.final_ll = 1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \ingroup CholmodSupport_Module
|
|
||||||
* \class CholmodSimplicialLDLT
|
|
||||||
* \brief A simplicial direct Cholesky (LDLT) factorization and solver based on Cholmod
|
|
||||||
*
|
|
||||||
* This class allows to solve for A.X = B sparse linear problems via a simplicial LDL^T Cholesky factorization
|
|
||||||
* using the Cholmod library.
|
|
||||||
* This simplicial variant is equivalent to Eigen's built-in SimplicialLDLT class. Therefore, it has little practical
|
|
||||||
* interest. The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices X and B can be
|
|
||||||
* either dense or sparse.
|
|
||||||
*
|
|
||||||
* \tparam MatrixType_ the type of the sparse matrix A, it must be a SparseMatrix<>
|
|
||||||
* \tparam UpLo_ the triangular part that will be used for the computations. It can be Lower
|
|
||||||
* or Upper. Default is Lower.
|
|
||||||
*
|
|
||||||
* \implsparsesolverconcept
|
|
||||||
*
|
|
||||||
* This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non
|
|
||||||
* compressed.
|
|
||||||
*
|
|
||||||
* \warning Only double precision real and complex scalar types are supported by Cholmod.
|
|
||||||
*
|
|
||||||
* \sa \ref TutorialSparseSolverConcept, class CholmodSupernodalLLT, class SimplicialLDLT
|
|
||||||
*/
|
|
||||||
template <typename MatrixType_, int UpLo_ = Lower>
|
|
||||||
class CholmodSimplicialLDLT : public CholmodBase<MatrixType_, UpLo_, CholmodSimplicialLDLT<MatrixType_, UpLo_> > {
|
|
||||||
typedef CholmodBase<MatrixType_, UpLo_, CholmodSimplicialLDLT> Base;
|
|
||||||
using Base::m_cholmod;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef MatrixType_ MatrixType;
|
|
||||||
typedef typename MatrixType::Scalar Scalar;
|
|
||||||
typedef typename MatrixType::RealScalar RealScalar;
|
|
||||||
typedef typename MatrixType::StorageIndex StorageIndex;
|
|
||||||
typedef Matrix<Scalar, Dynamic, 1> VectorType;
|
|
||||||
typedef TriangularView<const MatrixType, Eigen::UnitLower> MatrixL;
|
|
||||||
typedef TriangularView<const typename MatrixType::AdjointReturnType, Eigen::UnitUpper> MatrixU;
|
|
||||||
|
|
||||||
CholmodSimplicialLDLT() : Base() { init(); }
|
|
||||||
|
|
||||||
CholmodSimplicialLDLT(const MatrixType& matrix) : Base() {
|
|
||||||
init();
|
|
||||||
this->compute(matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
~CholmodSimplicialLDLT() {}
|
|
||||||
|
|
||||||
/** \returns a vector expression of the diagonal D */
|
|
||||||
inline VectorType vectorD() const {
|
|
||||||
auto cholmodL = viewAsEigen<Scalar, StorageIndex>(*Base::m_cholmodFactor);
|
|
||||||
|
|
||||||
VectorType D{cholmodL.rows()};
|
|
||||||
|
|
||||||
for (Index k = 0; k < cholmodL.outerSize(); ++k) {
|
|
||||||
typename decltype(cholmodL)::InnerIterator it{cholmodL, k};
|
|
||||||
D(k) = it.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
return D;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \returns an expression of the factor L */
|
|
||||||
inline MatrixL matrixL() const { return viewAsEigen<Scalar, StorageIndex>(*Base::m_cholmodFactor); }
|
|
||||||
|
|
||||||
/** \returns an expression of the factor U (= L^*) */
|
|
||||||
inline MatrixU matrixU() const { return matrixL().adjoint(); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void init() {
|
|
||||||
m_cholmod.final_asis = 1;
|
|
||||||
m_cholmod.supernodal = CHOLMOD_SIMPLICIAL;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \ingroup CholmodSupport_Module
|
|
||||||
* \class CholmodSupernodalLLT
|
|
||||||
* \brief A supernodal Cholesky (LLT) factorization and solver based on Cholmod
|
|
||||||
*
|
|
||||||
* This class allows to solve for A.X = B sparse linear problems via a supernodal LL^T Cholesky factorization
|
|
||||||
* using the Cholmod library.
|
|
||||||
* This supernodal variant performs best on dense enough problems, e.g., 3D FEM, or very high order 2D FEM.
|
|
||||||
* The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices
|
|
||||||
* X and B can be either dense or sparse.
|
|
||||||
*
|
|
||||||
* \tparam MatrixType_ the type of the sparse matrix A, it must be a SparseMatrix<>
|
|
||||||
* \tparam UpLo_ the triangular part that will be used for the computations. It can be Lower
|
|
||||||
* or Upper. Default is Lower.
|
|
||||||
*
|
|
||||||
* \implsparsesolverconcept
|
|
||||||
*
|
|
||||||
* This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non
|
|
||||||
* compressed.
|
|
||||||
*
|
|
||||||
* \warning Only double precision real and complex scalar types are supported by Cholmod.
|
|
||||||
*
|
|
||||||
* \sa \ref TutorialSparseSolverConcept
|
|
||||||
*/
|
|
||||||
template <typename MatrixType_, int UpLo_ = Lower>
|
|
||||||
class CholmodSupernodalLLT : public CholmodBase<MatrixType_, UpLo_, CholmodSupernodalLLT<MatrixType_, UpLo_> > {
|
|
||||||
typedef CholmodBase<MatrixType_, UpLo_, CholmodSupernodalLLT> Base;
|
|
||||||
using Base::m_cholmod;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef MatrixType_ MatrixType;
|
|
||||||
typedef typename MatrixType::Scalar Scalar;
|
|
||||||
typedef typename MatrixType::RealScalar RealScalar;
|
|
||||||
typedef typename MatrixType::StorageIndex StorageIndex;
|
|
||||||
|
|
||||||
CholmodSupernodalLLT() : Base() { init(); }
|
|
||||||
|
|
||||||
CholmodSupernodalLLT(const MatrixType& matrix) : Base() {
|
|
||||||
init();
|
|
||||||
this->compute(matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
~CholmodSupernodalLLT() {}
|
|
||||||
|
|
||||||
/** \returns an expression of the factor L */
|
|
||||||
inline MatrixType matrixL() const {
|
|
||||||
// Convert Cholmod factor's supernodal storage format to Eigen's CSC storage format
|
|
||||||
cholmod_sparse* cholmodL = internal::cm_factor_to_sparse(*Base::m_cholmodFactor, m_cholmod);
|
|
||||||
MatrixType L = viewAsEigen<Scalar, StorageIndex>(*cholmodL);
|
|
||||||
internal::cm_free_sparse<StorageIndex>(cholmodL, m_cholmod);
|
|
||||||
|
|
||||||
return L;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \returns an expression of the factor U (= L^*) */
|
|
||||||
inline MatrixType matrixU() const { return matrixL().adjoint(); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void init() {
|
|
||||||
m_cholmod.final_asis = 1;
|
|
||||||
m_cholmod.supernodal = CHOLMOD_SUPERNODAL;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \ingroup CholmodSupport_Module
|
|
||||||
* \class CholmodDecomposition
|
|
||||||
* \brief A general Cholesky factorization and solver based on Cholmod
|
|
||||||
*
|
|
||||||
* This class allows to solve for A.X = B sparse linear problems via a LL^T or LDL^T Cholesky factorization
|
|
||||||
* using the Cholmod library. The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices
|
|
||||||
* X and B can be either dense or sparse.
|
|
||||||
*
|
|
||||||
* This variant permits to change the underlying Cholesky method at runtime.
|
|
||||||
* On the other hand, it does not provide access to the result of the factorization.
|
|
||||||
* The default is to let Cholmod automatically choose between a simplicial and supernodal factorization.
|
|
||||||
*
|
|
||||||
* \tparam MatrixType_ the type of the sparse matrix A, it must be a SparseMatrix<>
|
|
||||||
* \tparam UpLo_ the triangular part that will be used for the computations. It can be Lower
|
|
||||||
* or Upper. Default is Lower.
|
|
||||||
*
|
|
||||||
* \implsparsesolverconcept
|
|
||||||
*
|
|
||||||
* This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non
|
|
||||||
* compressed.
|
|
||||||
*
|
|
||||||
* \warning Only double precision real and complex scalar types are supported by Cholmod.
|
|
||||||
*
|
|
||||||
* \sa \ref TutorialSparseSolverConcept
|
|
||||||
*/
|
|
||||||
template <typename MatrixType_, int UpLo_ = Lower>
|
|
||||||
class CholmodDecomposition : public CholmodBase<MatrixType_, UpLo_, CholmodDecomposition<MatrixType_, UpLo_> > {
|
|
||||||
typedef CholmodBase<MatrixType_, UpLo_, CholmodDecomposition> Base;
|
|
||||||
using Base::m_cholmod;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef MatrixType_ MatrixType;
|
|
||||||
|
|
||||||
CholmodDecomposition() : Base() { init(); }
|
|
||||||
|
|
||||||
CholmodDecomposition(const MatrixType& matrix) : Base() {
|
|
||||||
init();
|
|
||||||
this->compute(matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
~CholmodDecomposition() {}
|
|
||||||
|
|
||||||
void setMode(CholmodMode mode) {
|
|
||||||
switch (mode) {
|
|
||||||
case CholmodAuto:
|
|
||||||
m_cholmod.final_asis = 1;
|
|
||||||
m_cholmod.supernodal = CHOLMOD_AUTO;
|
|
||||||
break;
|
|
||||||
case CholmodSimplicialLLt:
|
|
||||||
m_cholmod.final_asis = 0;
|
|
||||||
m_cholmod.supernodal = CHOLMOD_SIMPLICIAL;
|
|
||||||
m_cholmod.final_ll = 1;
|
|
||||||
break;
|
|
||||||
case CholmodSupernodalLLt:
|
|
||||||
m_cholmod.final_asis = 1;
|
|
||||||
m_cholmod.supernodal = CHOLMOD_SUPERNODAL;
|
|
||||||
break;
|
|
||||||
case CholmodLDLt:
|
|
||||||
m_cholmod.final_asis = 1;
|
|
||||||
m_cholmod.supernodal = CHOLMOD_SIMPLICIAL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void init() {
|
|
||||||
m_cholmod.final_asis = 1;
|
|
||||||
m_cholmod.supernodal = CHOLMOD_AUTO;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_CHOLMODSUPPORT_H
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
#ifndef EIGEN_CHOLMODSUPPORT_MODULE_H
|
|
||||||
#error "Please include Eigen/CholmodSupport instead of including headers inside the src directory directly."
|
|
||||||
#endif
|
|
||||||
@@ -1,239 +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
|
|
||||||
|
|
||||||
// IWYU pragma: private
|
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
// Helper to cleanup the type of the increment:
|
|
||||||
template <typename T>
|
|
||||||
struct cleanup_seq_incr {
|
|
||||||
typedef typename cleanup_index_type<T, DynamicIndex>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
|
||||||
// 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:
|
|
||||||
constexpr ArithmeticSequence() = default;
|
|
||||||
constexpr ArithmeticSequence(FirstType first, SizeType size) : m_first(first), m_size(size) {}
|
|
||||||
constexpr 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 */
|
|
||||||
constexpr Index size() const { return m_size; }
|
|
||||||
|
|
||||||
/** \returns the first element \f$ a_0 \f$ in the sequence */
|
|
||||||
constexpr Index first() const { return m_first; }
|
|
||||||
|
|
||||||
/** \returns the value \f$ a_i \f$ at index \a i in the sequence. */
|
|
||||||
constexpr Index operator[](Index i) const { return m_first + i * m_incr; }
|
|
||||||
|
|
||||||
constexpr const FirstType& firstObject() const { return m_first; }
|
|
||||||
constexpr const SizeType& sizeObject() const { return m_size; }
|
|
||||||
constexpr const IncrType& incrObject() const { return m_incr; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
FirstType m_first;
|
|
||||||
SizeType m_size;
|
|
||||||
IncrType m_incr;
|
|
||||||
|
|
||||||
public:
|
|
||||||
constexpr 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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
|
|
||||||
/** \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, typename IncrType>
|
|
||||||
auto seq(FirstType f, LastType l, IncrType incr);
|
|
||||||
|
|
||||||
/** \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>
|
|
||||||
auto seq(FirstType f, LastType l);
|
|
||||||
|
|
||||||
#else // EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
|
|
||||||
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>()));
|
|
||||||
}
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
|
|
||||||
namespace placeholders {
|
|
||||||
|
|
||||||
/** \cpp11
|
|
||||||
* \returns a symbolic ArithmeticSequence representing the last \a size elements with increment \a incr.
|
|
||||||
*
|
|
||||||
* It is a shortcut for: \code seqN(last-(size-fix<1>)*incr, size, incr) \endcode
|
|
||||||
* \anchor Eigen_placeholders_lastN
|
|
||||||
* \sa lastN(SizeType), seqN(FirstType,SizeType), seq(FirstType,LastType,IncrType) */
|
|
||||||
template <typename SizeType, typename IncrType>
|
|
||||||
auto lastN(SizeType size, IncrType incr)
|
|
||||||
-> decltype(seqN(Eigen::placeholders::last - (size - fix<1>()) * incr, size, incr)) {
|
|
||||||
return seqN(Eigen::placeholders::last - (size - fix<1>()) * incr, size, incr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \cpp11
|
|
||||||
* \returns a symbolic ArithmeticSequence representing the last \a size elements with a unit increment.
|
|
||||||
*
|
|
||||||
* 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::placeholders::last + fix<1>() - size, size)) {
|
|
||||||
return seqN(Eigen::placeholders::last + fix<1>() - size, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace placeholders
|
|
||||||
|
|
||||||
/** \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::fix;
|
|
||||||
using Eigen::seq;
|
|
||||||
using Eigen::seqN;
|
|
||||||
using Eigen::placeholders::all;
|
|
||||||
using Eigen::placeholders::last;
|
|
||||||
using Eigen::placeholders::lastN; // c++11 only
|
|
||||||
using Eigen::placeholders::lastp1;
|
|
||||||
\endcode
|
|
||||||
*/
|
|
||||||
namespace indexing {
|
|
||||||
using Eigen::fix;
|
|
||||||
using Eigen::seq;
|
|
||||||
using Eigen::seqN;
|
|
||||||
using Eigen::placeholders::all;
|
|
||||||
using Eigen::placeholders::last;
|
|
||||||
using Eigen::placeholders::lastN;
|
|
||||||
using Eigen::placeholders::lastp1;
|
|
||||||
} // namespace indexing
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_ARITHMETIC_SEQUENCE_H
|
|
||||||
@@ -3,27 +3,28 @@
|
|||||||
//
|
//
|
||||||
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_ARRAY_H
|
#ifndef EIGEN_ARRAY_H
|
||||||
#define EIGEN_ARRAY_H
|
#define EIGEN_ARRAY_H
|
||||||
|
|
||||||
// IWYU pragma: private
|
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
template <typename Scalar_, int Rows_, int Cols_, int Options_, int MaxRows_, int MaxCols_>
|
|
||||||
struct traits<Array<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>>
|
|
||||||
: traits<Matrix<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>> {
|
|
||||||
typedef ArrayXpr XprKind;
|
|
||||||
typedef ArrayBase<Array<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>> XprBase;
|
|
||||||
};
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
/** \class Array
|
/** \class Array
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
*
|
*
|
||||||
@@ -36,21 +37,30 @@ struct traits<Array<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>>
|
|||||||
* API for the %Matrix class provides easy access to linear-algebra
|
* API for the %Matrix class provides easy access to linear-algebra
|
||||||
* operations.
|
* operations.
|
||||||
*
|
*
|
||||||
* See documentation of class Matrix for detailed information on the template parameters
|
|
||||||
* storage layout.
|
|
||||||
*
|
|
||||||
* This class can be extended with the help of the plugin mechanism described on the page
|
* This class can be extended with the help of the plugin mechanism described on the page
|
||||||
* \ref TopicCustomizing_Plugins by defining the preprocessor symbol \c EIGEN_ARRAY_PLUGIN.
|
* \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_ARRAY_PLUGIN.
|
||||||
*
|
*
|
||||||
* \sa \blank \ref TutorialArrayClass, \ref TopicClassHierarchy
|
* \sa \ref TutorialArrayClass, \ref TopicClassHierarchy
|
||||||
*/
|
*/
|
||||||
template <typename Scalar_, int Rows_, int Cols_, int Options_, int MaxRows_, int MaxCols_>
|
namespace internal {
|
||||||
class Array : public PlainObjectBase<Array<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>> {
|
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
|
||||||
|
struct traits<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > : traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
|
||||||
|
{
|
||||||
|
typedef ArrayXpr XprKind;
|
||||||
|
typedef ArrayBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > XprBase;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
|
||||||
|
class Array
|
||||||
|
: public PlainObjectBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef PlainObjectBase<Array> Base;
|
typedef PlainObjectBase<Array> Base;
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE(Array)
|
EIGEN_DENSE_PUBLIC_INTERFACE(Array)
|
||||||
|
|
||||||
enum { Options = Options_ };
|
enum { Options = _Options };
|
||||||
typedef typename Base::PlainObject PlainObject;
|
typedef typename Base::PlainObject PlainObject;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -60,6 +70,7 @@ class Array : public PlainObjectBase<Array<Scalar_, Rows_, Cols_, Options_, MaxR
|
|||||||
using Base::m_storage;
|
using Base::m_storage;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using Base::base;
|
using Base::base;
|
||||||
using Base::coeff;
|
using Base::coeff;
|
||||||
using Base::coeffRef;
|
using Base::coeffRef;
|
||||||
@@ -71,23 +82,11 @@ class Array : public PlainObjectBase<Array<Scalar_, Rows_, Cols_, Options_, MaxR
|
|||||||
* the usage of 'using'. This should be done only for operator=.
|
* the usage of 'using'. This should be done only for operator=.
|
||||||
*/
|
*/
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array& operator=(const EigenBase<OtherDerived>& other) {
|
EIGEN_STRONG_INLINE Array& operator=(const EigenBase<OtherDerived> &other)
|
||||||
|
{
|
||||||
return Base::operator=(other);
|
return Base::operator=(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set all the entries to \a value.
|
|
||||||
* \sa DenseBase::setConstant(), DenseBase::fill()
|
|
||||||
*/
|
|
||||||
/* This overload is needed because the usage of
|
|
||||||
* using Base::operator=;
|
|
||||||
* fails on MSVC. Since the code below is working with GCC and MSVC, we skipped
|
|
||||||
* the usage of 'using'. This should be done only for operator=.
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array& operator=(const Scalar& value) {
|
|
||||||
Base::setConstant(value);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Copies the value of the expression \a other into \c *this with automatic resizing.
|
/** Copies the value of the expression \a other into \c *this with automatic resizing.
|
||||||
*
|
*
|
||||||
* *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized),
|
* *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized),
|
||||||
@@ -98,19 +97,18 @@ class Array : public PlainObjectBase<Array<Scalar_, Rows_, Cols_, Options_, MaxR
|
|||||||
* remain row-vectors and vectors remain vectors.
|
* remain row-vectors and vectors remain vectors.
|
||||||
*/
|
*/
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array& operator=(const DenseBase<OtherDerived>& other) {
|
EIGEN_STRONG_INLINE Array& operator=(const ArrayBase<OtherDerived>& other)
|
||||||
|
{
|
||||||
return Base::_set(other);
|
return Base::_set(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** This is a special case of the templated operator=. Its purpose is to
|
||||||
* \brief Assigns arrays to each other.
|
* prevent a default operator= from hiding the templated operator=.
|
||||||
*
|
|
||||||
* \note This is a special case of the templated operator=. Its purpose is
|
|
||||||
* to prevent a default operator= from hiding the templated operator=.
|
|
||||||
*
|
|
||||||
* \callgraph
|
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array& operator=(const Array& other) { return Base::_set(other); }
|
EIGEN_STRONG_INLINE Array& operator=(const Array& other)
|
||||||
|
{
|
||||||
|
return Base::_set(other);
|
||||||
|
}
|
||||||
|
|
||||||
/** Default constructor.
|
/** Default constructor.
|
||||||
*
|
*
|
||||||
@@ -122,143 +120,129 @@ class Array : public PlainObjectBase<Array<Scalar_, Rows_, Cols_, Options_, MaxR
|
|||||||
*
|
*
|
||||||
* \sa resize(Index,Index)
|
* \sa resize(Index,Index)
|
||||||
*/
|
*/
|
||||||
#ifdef EIGEN_INITIALIZE_COEFFS
|
EIGEN_STRONG_INLINE explicit Array() : Base()
|
||||||
EIGEN_DEVICE_FUNC constexpr Array() : Base() { EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED }
|
{
|
||||||
#else
|
Base::_check_template_params();
|
||||||
EIGEN_DEVICE_FUNC constexpr Array() = default;
|
EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
|
||||||
#endif
|
|
||||||
/** \brief Move constructor */
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Array(Array&&) = default;
|
|
||||||
EIGEN_DEVICE_FUNC Array& operator=(Array&& other) noexcept(std::is_nothrow_move_assignable<Scalar>::value) {
|
|
||||||
Base::operator=(std::move(other));
|
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Construct a row of column vector with fixed size from an arbitrary number of coefficients.
|
|
||||||
*
|
|
||||||
* \only_for_vectors
|
|
||||||
*
|
|
||||||
* This constructor is for 1D array or vectors with more than 4 coefficients.
|
|
||||||
*
|
|
||||||
* \warning To construct a column (resp. row) vector of fixed length, the number of values passed to this
|
|
||||||
* constructor must match 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 constexpr Array(const std::initializer_list<std::initializer_list<Scalar>>& list) : Base(list) {}
|
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
template <typename T>
|
// FIXME is it still needed ??
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit Array(const T& x) {
|
/** \internal */
|
||||||
Base::template _init1<T>(x);
|
Array(internal::constructor_without_unaligned_array_assert)
|
||||||
|
: Base(internal::constructor_without_unaligned_array_assert())
|
||||||
|
{
|
||||||
|
Base::_check_template_params();
|
||||||
|
EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template <typename T0, typename T1>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array(const T0& val0, const T1& val1) {
|
|
||||||
this->template _init2<T0, T1>(val0, val1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
/** \brief Constructs a fixed-sized array initialized with coefficients starting at \a data */
|
|
||||||
EIGEN_DEVICE_FUNC explicit Array(const Scalar* data);
|
|
||||||
/** Constructs a vector or row-vector with given dimension. \only_for_vectors
|
/** Constructs a vector or row-vector with given dimension. \only_for_vectors
|
||||||
*
|
*
|
||||||
* Note that this is only useful for dynamic-size vectors. For fixed-size vectors,
|
* Note that this is only useful for dynamic-size vectors. For fixed-size vectors,
|
||||||
* it is redundant to pass the dimension here, so it makes more sense to use the default
|
* it is redundant to pass the dimension here, so it makes more sense to use the default
|
||||||
* constructor Array() instead.
|
* constructor Matrix() instead.
|
||||||
*/
|
*/
|
||||||
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
|
: Base(dim, RowsAtCompileTime == 1 ? 1 : dim, ColsAtCompileTime == 1 ? 1 : dim)
|
||||||
* \sa const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args */
|
{
|
||||||
Array(const Scalar& value);
|
Base::_check_template_params();
|
||||||
/** constructs an uninitialized array with \a rows rows and \a cols columns.
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Array)
|
||||||
|
eigen_assert(dim >= 0);
|
||||||
|
eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim);
|
||||||
|
EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
template<typename T0, typename T1>
|
||||||
|
EIGEN_STRONG_INLINE Array(const T0& x, const T1& y)
|
||||||
|
{
|
||||||
|
Base::_check_template_params();
|
||||||
|
this->template _init2<T0,T1>(x, y);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/** constructs an uninitialized matrix with \a rows rows and \a cols columns.
|
||||||
*
|
*
|
||||||
* This is useful for dynamic-size arrays. For fixed-size arrays,
|
* This is useful for dynamic-size matrices. For fixed-size matrices,
|
||||||
* it is redundant to pass these parameters, so one should use the default constructor
|
* it is redundant to pass these parameters, so one should use the default constructor
|
||||||
* Array() instead. */
|
* Matrix() 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& x, const Scalar& y);
|
||||||
Array(const Scalar& val0, const Scalar& val1);
|
#endif
|
||||||
#endif // end EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
|
|
||||||
/** 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_STRONG_INLINE Array(const Scalar& x, const Scalar& y, const Scalar& z)
|
||||||
*/
|
{
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2) {
|
Base::_check_template_params();
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 3)
|
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 3)
|
||||||
m_storage.data()[0] = val0;
|
m_storage.data()[0] = x;
|
||||||
m_storage.data()[1] = val1;
|
m_storage.data()[1] = y;
|
||||||
m_storage.data()[2] = val2;
|
m_storage.data()[2] = z;
|
||||||
}
|
}
|
||||||
/** 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_STRONG_INLINE Array(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w)
|
||||||
*/
|
{
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2,
|
Base::_check_template_params();
|
||||||
const Scalar& val3) {
|
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 4)
|
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 4)
|
||||||
m_storage.data()[0] = val0;
|
m_storage.data()[0] = x;
|
||||||
m_storage.data()[1] = val1;
|
m_storage.data()[1] = y;
|
||||||
m_storage.data()[2] = val2;
|
m_storage.data()[2] = z;
|
||||||
m_storage.data()[3] = val3;
|
m_storage.data()[3] = w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
explicit Array(const Scalar *data);
|
||||||
|
|
||||||
|
/** Constructor copying the value of the expression \a other */
|
||||||
|
template<typename OtherDerived>
|
||||||
|
EIGEN_STRONG_INLINE Array(const ArrayBase<OtherDerived>& other)
|
||||||
|
: Base(other.rows() * other.cols(), other.rows(), other.cols())
|
||||||
|
{
|
||||||
|
Base::_check_template_params();
|
||||||
|
Base::_set_noalias(other);
|
||||||
|
}
|
||||||
/** Copy constructor */
|
/** Copy constructor */
|
||||||
EIGEN_DEVICE_FUNC constexpr Array(const Array&) = default;
|
EIGEN_STRONG_INLINE Array(const Array& other)
|
||||||
|
: Base(other.rows() * other.cols(), other.rows(), other.cols())
|
||||||
|
{
|
||||||
|
Base::_check_template_params();
|
||||||
|
Base::_set_noalias(other);
|
||||||
|
}
|
||||||
|
/** Copy constructor with in-place evaluation */
|
||||||
|
template<typename OtherDerived>
|
||||||
|
EIGEN_STRONG_INLINE Array(const ReturnByValue<OtherDerived>& other)
|
||||||
|
{
|
||||||
|
Base::_check_template_params();
|
||||||
|
Base::resize(other.rows(), other.cols());
|
||||||
|
other.evalTo(*this);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
struct PrivateType {};
|
|
||||||
|
|
||||||
public:
|
|
||||||
/** \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) */
|
/** \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Array(
|
EIGEN_STRONG_INLINE Array(const EigenBase<OtherDerived> &other)
|
||||||
const EigenBase<OtherDerived>& other,
|
: Base(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
|
||||||
std::enable_if_t<internal::is_convertible<typename OtherDerived::Scalar, Scalar>::value, PrivateType> =
|
{
|
||||||
PrivateType())
|
Base::_check_template_params();
|
||||||
: Base(other.derived()) {}
|
Base::resize(other.rows(), other.cols());
|
||||||
|
*this = other;
|
||||||
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index innerStride() const noexcept { return 1; }
|
/** Override MatrixBase::swap() since for dynamic-sized matrices of same type it is enough to swap the
|
||||||
EIGEN_DEVICE_FUNC constexpr Index outerStride() const noexcept { return this->innerSize(); }
|
* data pointers.
|
||||||
|
*/
|
||||||
|
template<typename OtherDerived>
|
||||||
|
void swap(ArrayBase<OtherDerived> const & other)
|
||||||
|
{ this->_swap(other.derived()); }
|
||||||
|
|
||||||
|
inline Index innerStride() const { return 1; }
|
||||||
|
inline Index outerStride() const { return this->innerSize(); }
|
||||||
|
|
||||||
#ifdef EIGEN_ARRAY_PLUGIN
|
#ifdef EIGEN_ARRAY_PLUGIN
|
||||||
#include EIGEN_ARRAY_PLUGIN
|
#include EIGEN_ARRAY_PLUGIN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
template<typename MatrixType, typename OtherDerived, bool SwapPointers>
|
template<typename MatrixType, typename OtherDerived, bool SwapPointers>
|
||||||
friend struct internal::matrix_swap_impl;
|
friend struct internal::matrix_swap_impl;
|
||||||
};
|
};
|
||||||
@@ -266,26 +250,19 @@ class Array : public PlainObjectBase<Array<Scalar_, Rows_, Cols_, Options_, MaxR
|
|||||||
/** \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:
|
||||||
*
|
*
|
||||||
* \c ArrayRowsColsType where \c Rows and \c Cols can be \c 2,\c 3,\c 4 for fixed size square matrices or \c X for
|
* \c ArrayRowsColsType where \c Rows and \c Cols can be \c 2,\c 3,\c 4 for fixed size square matrices or \c X for dynamic size,
|
||||||
* dynamic size, and where \c Type can be \c i for integer, \c f for float, \c d for double, \c cf for complex float, \c
|
* and where \c Type can be \c i for integer, \c f for float, \c d for double, \c cf for complex float, \c cd
|
||||||
* cd for complex double.
|
* for complex double.
|
||||||
*
|
*
|
||||||
* For example, \c Array33d is a fixed-size 3x3 array type of doubles, and \c ArrayXXf is a dynamic-size matrix of
|
* For example, \c Array33d is a fixed-size 3x3 array type of doubles, and \c ArrayXXf is a dynamic-size matrix of floats.
|
||||||
* floats.
|
|
||||||
*
|
*
|
||||||
* 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
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -318,38 +295,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
|
|
||||||
|
|
||||||
#define EIGEN_MAKE_ARRAY_TYPEDEFS(Size, SizeSuffix) \
|
#undef EIGEN_MAKE_ARRAY_TYPEDEFS_LARGE
|
||||||
/** \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
|
|
||||||
|
|
||||||
#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; \
|
||||||
@@ -360,7 +307,7 @@ EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(4)
|
|||||||
EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \
|
EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \
|
||||||
EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \
|
EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \
|
||||||
EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \
|
EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \
|
||||||
EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X)
|
EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X) \
|
||||||
|
|
||||||
#define EIGEN_USING_ARRAY_TYPEDEFS \
|
#define EIGEN_USING_ARRAY_TYPEDEFS \
|
||||||
EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(i) \
|
EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(i) \
|
||||||
@@ -369,6 +316,5 @@ EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(4)
|
|||||||
EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cf) \
|
EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cf) \
|
||||||
EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cd)
|
EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cd)
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_ARRAY_H
|
#endif // EIGEN_ARRAY_H
|
||||||
|
|||||||
@@ -3,20 +3,29 @@
|
|||||||
//
|
//
|
||||||
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_ARRAYBASE_H
|
#ifndef EIGEN_ARRAYBASE_H
|
||||||
#define EIGEN_ARRAYBASE_H
|
#define EIGEN_ARRAYBASE_H
|
||||||
|
|
||||||
// IWYU pragma: private
|
template<typename ExpressionType> class MatrixWrapper;
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
template <typename ExpressionType>
|
|
||||||
class MatrixWrapper;
|
|
||||||
|
|
||||||
/** \class ArrayBase
|
/** \class ArrayBase
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
@@ -25,7 +34,7 @@ class MatrixWrapper;
|
|||||||
*
|
*
|
||||||
* An array is similar to a dense vector or matrix. While matrices are mathematical
|
* An array is similar to a dense vector or matrix. While matrices are mathematical
|
||||||
* objects with well defined linear algebra operators, an array is just a collection
|
* objects with well defined linear algebra operators, an array is just a collection
|
||||||
* of scalar values arranged in a one or two dimensional fashion. As the main consequence,
|
* of scalar values arranged in a one or two dimensionnal fashion. As the main consequence,
|
||||||
* all operations applied to an array are performed coefficient wise. Furthermore,
|
* all operations applied to an array are performed coefficient wise. Furthermore,
|
||||||
* arrays support scalar math functions of the c++ standard library (e.g., std::sin(x)), and convenient
|
* arrays support scalar math functions of the c++ standard library (e.g., std::sin(x)), and convenient
|
||||||
* constructors allowing to easily write generic code working for both scalar values
|
* constructors allowing to easily write generic code working for both scalar values
|
||||||
@@ -36,12 +45,13 @@ class MatrixWrapper;
|
|||||||
* \tparam Derived is the derived type, e.g., an array or an expression type.
|
* \tparam Derived is the derived type, e.g., an array or an expression type.
|
||||||
*
|
*
|
||||||
* This class can be extended with the help of the plugin mechanism described on the page
|
* This class can be extended with the help of the plugin mechanism described on the page
|
||||||
* \ref TopicCustomizing_Plugins by defining the preprocessor symbol \c EIGEN_ARRAYBASE_PLUGIN.
|
* \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_ARRAYBASE_PLUGIN.
|
||||||
*
|
*
|
||||||
* \sa class MatrixBase, \ref TopicClassHierarchy
|
* \sa class MatrixBase, \ref TopicClassHierarchy
|
||||||
*/
|
*/
|
||||||
template <typename Derived>
|
template<typename Derived> class ArrayBase
|
||||||
class ArrayBase : public DenseBase<Derived> {
|
: public DenseBase<Derived>
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
/** The base class for a given storage type. */
|
/** The base class for a given storage type. */
|
||||||
@@ -49,30 +59,34 @@ class ArrayBase : public DenseBase<Derived> {
|
|||||||
|
|
||||||
typedef ArrayBase Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl;
|
typedef ArrayBase Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl;
|
||||||
|
|
||||||
|
using internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar,
|
||||||
|
typename NumTraits<typename internal::traits<Derived>::Scalar>::Real>::operator*;
|
||||||
|
|
||||||
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
||||||
|
typedef typename internal::traits<Derived>::Index Index;
|
||||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||||
typedef typename internal::packet_traits<Scalar>::type PacketScalar;
|
typedef typename internal::packet_traits<Scalar>::type PacketScalar;
|
||||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||||
|
|
||||||
typedef DenseBase<Derived> Base;
|
typedef DenseBase<Derived> Base;
|
||||||
using Base::ColsAtCompileTime;
|
|
||||||
using Base::Flags;
|
|
||||||
using Base::IsVectorAtCompileTime;
|
|
||||||
using Base::MaxColsAtCompileTime;
|
|
||||||
using Base::MaxRowsAtCompileTime;
|
|
||||||
using Base::MaxSizeAtCompileTime;
|
|
||||||
using Base::RowsAtCompileTime;
|
using Base::RowsAtCompileTime;
|
||||||
|
using Base::ColsAtCompileTime;
|
||||||
using Base::SizeAtCompileTime;
|
using Base::SizeAtCompileTime;
|
||||||
|
using Base::MaxRowsAtCompileTime;
|
||||||
|
using Base::MaxColsAtCompileTime;
|
||||||
|
using Base::MaxSizeAtCompileTime;
|
||||||
|
using Base::IsVectorAtCompileTime;
|
||||||
|
using Base::Flags;
|
||||||
|
using Base::CoeffReadCost;
|
||||||
|
|
||||||
|
using Base::derived;
|
||||||
|
using Base::const_cast_derived;
|
||||||
|
using Base::rows;
|
||||||
|
using Base::cols;
|
||||||
|
using Base::size;
|
||||||
using Base::coeff;
|
using Base::coeff;
|
||||||
using Base::coeffRef;
|
using Base::coeffRef;
|
||||||
using Base::cols;
|
|
||||||
using Base::const_cast_derived;
|
|
||||||
using Base::derived;
|
|
||||||
using Base::lazyAssign;
|
using Base::lazyAssign;
|
||||||
using Base::rows;
|
|
||||||
using Base::size;
|
|
||||||
using Base::operator-;
|
|
||||||
using Base::operator=;
|
using Base::operator=;
|
||||||
using Base::operator+=;
|
using Base::operator+=;
|
||||||
using Base::operator-=;
|
using Base::operator-=;
|
||||||
@@ -81,49 +95,102 @@ class ArrayBase : public DenseBase<Derived> {
|
|||||||
|
|
||||||
typedef typename Base::CoeffReturnType CoeffReturnType;
|
typedef typename Base::CoeffReturnType CoeffReturnType;
|
||||||
|
|
||||||
typedef typename Base::PlainObject PlainObject;
|
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
|
||||||
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
/** \internal the plain matrix type corresponding to this expression. Note that is not necessarily
|
||||||
|
* exactly the return type of eval(): in the case of plain matrices, the return type of eval() is a const
|
||||||
|
* reference to a matrix, not a matrix! It is however guaranteed that the return type of eval() is either
|
||||||
|
* PlainObject or const PlainObject&.
|
||||||
|
*/
|
||||||
|
typedef Array<typename internal::traits<Derived>::Scalar,
|
||||||
|
internal::traits<Derived>::RowsAtCompileTime,
|
||||||
|
internal::traits<Derived>::ColsAtCompileTime,
|
||||||
|
AutoAlign | (internal::traits<Derived>::Flags&RowMajorBit ? RowMajor : ColMajor),
|
||||||
|
internal::traits<Derived>::MaxRowsAtCompileTime,
|
||||||
|
internal::traits<Derived>::MaxColsAtCompileTime
|
||||||
|
> PlainObject;
|
||||||
|
|
||||||
|
|
||||||
/** \internal Represents a matrix with all coefficients equal to one another*/
|
/** \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>,Derived> ConstantReturnType;
|
||||||
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
|
||||||
#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::ArrayBase
|
#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::ArrayBase
|
||||||
#define EIGEN_DOC_UNARY_ADDONS(X, Y)
|
# include "../plugins/CommonCwiseUnaryOps.h"
|
||||||
#include "../plugins/MatrixCwiseUnaryOps.inc"
|
# include "../plugins/MatrixCwiseUnaryOps.h"
|
||||||
#include "../plugins/ArrayCwiseUnaryOps.inc"
|
# include "../plugins/ArrayCwiseUnaryOps.h"
|
||||||
#include "../plugins/CommonCwiseBinaryOps.inc"
|
# include "../plugins/CommonCwiseBinaryOps.h"
|
||||||
#include "../plugins/MatrixCwiseBinaryOps.inc"
|
# include "../plugins/MatrixCwiseBinaryOps.h"
|
||||||
#include "../plugins/ArrayCwiseBinaryOps.inc"
|
# include "../plugins/ArrayCwiseBinaryOps.h"
|
||||||
# ifdef EIGEN_ARRAYBASE_PLUGIN
|
# ifdef EIGEN_ARRAYBASE_PLUGIN
|
||||||
# include EIGEN_ARRAYBASE_PLUGIN
|
# include EIGEN_ARRAYBASE_PLUGIN
|
||||||
# endif
|
# endif
|
||||||
#undef EIGEN_CURRENT_STORAGE_BASE_CLASS
|
#undef EIGEN_CURRENT_STORAGE_BASE_CLASS
|
||||||
#undef EIGEN_DOC_UNARY_ADDONS
|
|
||||||
|
|
||||||
/** Special case of the template operator=, in order to prevent the compiler
|
/** Special case of the template operator=, in order to prevent the compiler
|
||||||
* from generating a default operator= (issue hit with g++ 4.1)
|
* from generating a default operator= (issue hit with g++ 4.1)
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const ArrayBase& other) {
|
Derived& operator=(const ArrayBase& other)
|
||||||
internal::call_assignment(derived(), other.derived());
|
{
|
||||||
return derived();
|
return internal::assign_selector<Derived,Derived>::run(derived(), other.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set all the entries to \a value.
|
Derived& operator+=(const Scalar& scalar)
|
||||||
* \sa DenseBase::setConstant(), DenseBase::fill() */
|
{ return *this = derived() + scalar; }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const Scalar& value) {
|
Derived& operator-=(const Scalar& scalar)
|
||||||
Base::setConstant(value);
|
{ return *this = derived() - scalar; }
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator+=(const Scalar& other) {
|
template<typename OtherDerived>
|
||||||
internal::call_assignment(this->derived(), PlainObject::Constant(rows(), cols(), other),
|
Derived& operator+=(const ArrayBase<OtherDerived>& other);
|
||||||
internal::add_assign_op<Scalar, Scalar>());
|
template<typename OtherDerived>
|
||||||
return derived();
|
Derived& operator-=(const ArrayBase<OtherDerived>& other);
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator-=(const Scalar& other) {
|
template<typename OtherDerived>
|
||||||
internal::call_assignment(this->derived(), PlainObject::Constant(rows(), cols(), other),
|
Derived& operator*=(const ArrayBase<OtherDerived>& other);
|
||||||
internal::sub_assign_op<Scalar, Scalar>());
|
|
||||||
|
template<typename OtherDerived>
|
||||||
|
Derived& operator/=(const ArrayBase<OtherDerived>& other);
|
||||||
|
|
||||||
|
public:
|
||||||
|
ArrayBase<Derived>& array() { return *this; }
|
||||||
|
const ArrayBase<Derived>& array() const { return *this; }
|
||||||
|
|
||||||
|
/** \returns an \link MatrixBase Matrix \endlink expression of this array
|
||||||
|
* \sa MatrixBase::array() */
|
||||||
|
MatrixWrapper<Derived> matrix() { return derived(); }
|
||||||
|
const MatrixWrapper<Derived> matrix() const { return derived(); }
|
||||||
|
|
||||||
|
// template<typename Dest>
|
||||||
|
// inline void evalTo(Dest& dst) const { dst = matrix(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ArrayBase() : Base() {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit ArrayBase(Index);
|
||||||
|
ArrayBase(Index,Index);
|
||||||
|
template<typename OtherDerived> explicit ArrayBase(const ArrayBase<OtherDerived>&);
|
||||||
|
protected:
|
||||||
|
// mixing arrays and matrices is not legal
|
||||||
|
template<typename OtherDerived> Derived& operator+=(const MatrixBase<OtherDerived>& )
|
||||||
|
{EIGEN_STATIC_ASSERT(sizeof(typename OtherDerived::Scalar)==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES);}
|
||||||
|
// mixing arrays and matrices is not legal
|
||||||
|
template<typename OtherDerived> Derived& operator-=(const MatrixBase<OtherDerived>& )
|
||||||
|
{EIGEN_STATIC_ASSERT(sizeof(typename OtherDerived::Scalar)==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES);}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** replaces \c *this by \c *this - \a other.
|
||||||
|
*
|
||||||
|
* \returns a reference to \c *this
|
||||||
|
*/
|
||||||
|
template<typename Derived>
|
||||||
|
template<typename OtherDerived>
|
||||||
|
EIGEN_STRONG_INLINE Derived &
|
||||||
|
ArrayBase<Derived>::operator-=(const ArrayBase<OtherDerived> &other)
|
||||||
|
{
|
||||||
|
SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, Derived, OtherDerived> tmp(derived());
|
||||||
|
tmp = other.derived();
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,19 +198,13 @@ class ArrayBase : public DenseBase<Derived> {
|
|||||||
*
|
*
|
||||||
* \returns a reference to \c *this
|
* \returns a reference to \c *this
|
||||||
*/
|
*/
|
||||||
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator+=(const ArrayBase<OtherDerived>& other) {
|
EIGEN_STRONG_INLINE Derived &
|
||||||
call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar, typename OtherDerived::Scalar>());
|
ArrayBase<Derived>::operator+=(const ArrayBase<OtherDerived>& other)
|
||||||
return derived();
|
{
|
||||||
}
|
SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, Derived, OtherDerived> tmp(derived());
|
||||||
|
tmp = other.derived();
|
||||||
/** replaces \c *this by \c *this - \a other.
|
|
||||||
*
|
|
||||||
* \returns a reference to \c *this
|
|
||||||
*/
|
|
||||||
template <typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator-=(const ArrayBase<OtherDerived>& other) {
|
|
||||||
call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar, typename OtherDerived::Scalar>());
|
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,9 +212,13 @@ class ArrayBase : public DenseBase<Derived> {
|
|||||||
*
|
*
|
||||||
* \returns a reference to \c *this
|
* \returns a reference to \c *this
|
||||||
*/
|
*/
|
||||||
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator*=(const ArrayBase<OtherDerived>& other) {
|
EIGEN_STRONG_INLINE Derived &
|
||||||
call_assignment(derived(), other.derived(), internal::mul_assign_op<Scalar, typename OtherDerived::Scalar>());
|
ArrayBase<Derived>::operator*=(const ArrayBase<OtherDerived>& other)
|
||||||
|
{
|
||||||
|
SelfCwiseBinaryOp<internal::scalar_product_op<Scalar>, Derived, OtherDerived> tmp(derived());
|
||||||
|
tmp = other.derived();
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,50 +226,14 @@ class ArrayBase : public DenseBase<Derived> {
|
|||||||
*
|
*
|
||||||
* \returns a reference to \c *this
|
* \returns a reference to \c *this
|
||||||
*/
|
*/
|
||||||
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator/=(const ArrayBase<OtherDerived>& other) {
|
EIGEN_STRONG_INLINE Derived &
|
||||||
call_assignment(derived(), other.derived(), internal::div_assign_op<Scalar, typename OtherDerived::Scalar>());
|
ArrayBase<Derived>::operator/=(const ArrayBase<OtherDerived>& other)
|
||||||
|
{
|
||||||
|
SelfCwiseBinaryOp<internal::scalar_quotient_op<Scalar>, Derived, OtherDerived> tmp(derived());
|
||||||
|
tmp = other.derived();
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
EIGEN_DEVICE_FUNC constexpr ArrayBase<Derived>& array() { return *this; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr const ArrayBase<Derived>& array() const { return *this; }
|
|
||||||
|
|
||||||
/** \returns an \link Eigen::MatrixBase Matrix \endlink expression of this array
|
|
||||||
* \sa MatrixBase::array() */
|
|
||||||
EIGEN_DEVICE_FUNC constexpr MatrixWrapper<Derived> matrix() { return MatrixWrapper<Derived>(derived()); }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr const MatrixWrapper<const Derived> matrix() const {
|
|
||||||
return MatrixWrapper<const Derived>(derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
EIGEN_DEFAULT_COPY_CONSTRUCTOR(ArrayBase)
|
|
||||||
EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(ArrayBase)
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit ArrayBase(Index);
|
|
||||||
ArrayBase(Index, Index);
|
|
||||||
template <typename OtherDerived>
|
|
||||||
explicit ArrayBase(const ArrayBase<OtherDerived>&);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// mixing arrays and matrices is not legal
|
|
||||||
template <typename OtherDerived>
|
|
||||||
Derived& operator+=(const MatrixBase<OtherDerived>&) {
|
|
||||||
EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar)) == -1,
|
|
||||||
YOU_CANNOT_MIX_ARRAYS_AND_MATRICES);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
// mixing arrays and matrices is not legal
|
|
||||||
template <typename OtherDerived>
|
|
||||||
Derived& operator-=(const MatrixBase<OtherDerived>&) {
|
|
||||||
EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar)) == -1,
|
|
||||||
YOU_CANNOT_MIX_ARRAYS_AND_MATRICES);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_ARRAYBASE_H
|
#endif // EIGEN_ARRAYBASE_H
|
||||||
|
|||||||
@@ -3,92 +3,133 @@
|
|||||||
//
|
//
|
||||||
// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
|
// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_ARRAYWRAPPER_H
|
#ifndef EIGEN_ARRAYWRAPPER_H
|
||||||
#define EIGEN_ARRAYWRAPPER_H
|
#define EIGEN_ARRAYWRAPPER_H
|
||||||
|
|
||||||
// IWYU pragma: private
|
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
/** \class ArrayWrapper
|
/** \class ArrayWrapper
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
*
|
*
|
||||||
* \brief Expression of a mathematical vector or matrix as an array object
|
* \brief Expression of a mathematical vector or matrix as an array object
|
||||||
*
|
*
|
||||||
* This class is the return type of MatrixBase::array(), and most of the time
|
* This class is the return type of MatrixBase::array(), and most of the time
|
||||||
* this is the only way it is used.
|
* this is the only way it is use.
|
||||||
*
|
*
|
||||||
* \sa MatrixBase::array(), class MatrixWrapper
|
* \sa MatrixBase::array(), class MatrixWrapper
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
template<typename ExpressionType>
|
template<typename ExpressionType>
|
||||||
struct traits<ArrayWrapper<ExpressionType> > : public traits<remove_all_t<typename ExpressionType::Nested> > {
|
struct traits<ArrayWrapper<ExpressionType> >
|
||||||
|
: public traits<typename remove_all<typename ExpressionType::Nested>::type >
|
||||||
|
{
|
||||||
typedef ArrayXpr XprKind;
|
typedef ArrayXpr XprKind;
|
||||||
// Let's remove NestByRefBit
|
|
||||||
enum {
|
|
||||||
Flags0 = traits<remove_all_t<typename ExpressionType::Nested> >::Flags,
|
|
||||||
LvalueBitFlag = is_lvalue<ExpressionType>::value ? LvalueBit : 0,
|
|
||||||
Flags = (Flags0 & ~(NestByRefBit | LvalueBit)) | LvalueBitFlag
|
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
template<typename ExpressionType>
|
template<typename ExpressionType>
|
||||||
class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> > {
|
class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
typedef ArrayBase<ArrayWrapper> Base;
|
typedef ArrayBase<ArrayWrapper> Base;
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE(ArrayWrapper)
|
EIGEN_DENSE_PUBLIC_INTERFACE(ArrayWrapper)
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ArrayWrapper)
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ArrayWrapper)
|
||||||
typedef internal::remove_all_t<ExpressionType> NestedExpression;
|
|
||||||
|
|
||||||
typedef std::conditional_t<internal::is_lvalue<ExpressionType>::value, Scalar, const Scalar>
|
typedef typename internal::conditional<
|
||||||
ScalarWithConstIfNotLvalue;
|
internal::is_lvalue<ExpressionType>::value,
|
||||||
|
Scalar,
|
||||||
|
const Scalar
|
||||||
|
>::type ScalarWithConstIfNotLvalue;
|
||||||
|
|
||||||
typedef typename internal::ref_selector<ExpressionType>::non_const_type NestedExpressionType;
|
typedef typename internal::nested<ExpressionType>::type NestedExpressionType;
|
||||||
|
|
||||||
using Base::coeffRef;
|
inline ArrayWrapper(const ExpressionType& matrix) : m_expression(matrix) {}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr explicit EIGEN_STRONG_INLINE ArrayWrapper(ExpressionType& matrix)
|
inline Index rows() const { return m_expression.rows(); }
|
||||||
: m_expression(matrix) {}
|
inline Index cols() const { return m_expression.cols(); }
|
||||||
|
inline Index outerStride() const { return m_expression.outerStride(); }
|
||||||
|
inline Index innerStride() const { return m_expression.innerStride(); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index rows() const noexcept { return m_expression.rows(); }
|
inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
|
||||||
EIGEN_DEVICE_FUNC constexpr Index cols() const noexcept { return m_expression.cols(); }
|
inline const Scalar* data() const { return m_expression.data(); }
|
||||||
EIGEN_DEVICE_FUNC constexpr Index outerStride() const noexcept { return m_expression.outerStride(); }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index innerStride() const noexcept { return m_expression.innerStride(); }
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
|
inline const CoeffReturnType coeff(Index row, Index col) const
|
||||||
EIGEN_DEVICE_FUNC constexpr const Scalar* data() const { return m_expression.data(); }
|
{
|
||||||
|
return m_expression.coeff(row, col);
|
||||||
EIGEN_DEVICE_FUNC inline const Scalar& coeffRef(Index rowId, Index colId) const {
|
|
||||||
return m_expression.coeffRef(rowId, colId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline const Scalar& coeffRef(Index index) const { return m_expression.coeffRef(index); }
|
inline Scalar& coeffRef(Index row, Index col)
|
||||||
|
{
|
||||||
|
return m_expression.const_cast_derived().coeffRef(row, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Scalar& coeffRef(Index row, Index col) const
|
||||||
|
{
|
||||||
|
return m_expression.const_cast_derived().coeffRef(row, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const CoeffReturnType coeff(Index index) const
|
||||||
|
{
|
||||||
|
return m_expression.coeff(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Scalar& coeffRef(Index index)
|
||||||
|
{
|
||||||
|
return m_expression.const_cast_derived().coeffRef(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Scalar& coeffRef(Index index) const
|
||||||
|
{
|
||||||
|
return m_expression.const_cast_derived().coeffRef(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
inline const PacketScalar packet(Index row, Index col) const
|
||||||
|
{
|
||||||
|
return m_expression.template packet<LoadMode>(row, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
inline void writePacket(Index row, Index col, const PacketScalar& x)
|
||||||
|
{
|
||||||
|
m_expression.const_cast_derived().template writePacket<LoadMode>(row, col, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
inline const PacketScalar packet(Index index) const
|
||||||
|
{
|
||||||
|
return m_expression.template packet<LoadMode>(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
inline void writePacket(Index index, const PacketScalar& x)
|
||||||
|
{
|
||||||
|
m_expression.const_cast_derived().template writePacket<LoadMode>(index, x);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
EIGEN_DEVICE_FUNC inline void evalTo(Dest& dst) const {
|
inline void evalTo(Dest& dst) const { dst = m_expression; }
|
||||||
dst = m_expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr const internal::remove_all_t<NestedExpressionType>& nestedExpression() const {
|
|
||||||
return m_expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Forwards the resizing request to the nested expression
|
|
||||||
* \sa DenseBase::resize(Index) */
|
|
||||||
EIGEN_DEVICE_FUNC void resize(Index newSize) { m_expression.resize(newSize); }
|
|
||||||
/** Forwards the resizing request to the nested expression
|
|
||||||
* \sa DenseBase::resize(Index,Index)*/
|
|
||||||
EIGEN_DEVICE_FUNC void resize(Index rows, Index cols) { m_expression.resize(rows, cols); }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
NestedExpressionType m_expression;
|
const NestedExpressionType m_expression;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \class MatrixWrapper
|
/** \class MatrixWrapper
|
||||||
@@ -97,70 +138,102 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> > {
|
|||||||
* \brief Expression of an array as a mathematical vector or matrix
|
* \brief Expression of an array as a mathematical vector or matrix
|
||||||
*
|
*
|
||||||
* This class is the return type of ArrayBase::matrix(), and most of the time
|
* This class is the return type of ArrayBase::matrix(), and most of the time
|
||||||
* this is the only way it is used.
|
* this is the only way it is use.
|
||||||
*
|
*
|
||||||
* \sa MatrixBase::matrix(), class ArrayWrapper
|
* \sa MatrixBase::matrix(), class ArrayWrapper
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
template<typename ExpressionType>
|
template<typename ExpressionType>
|
||||||
struct traits<MatrixWrapper<ExpressionType> > : public traits<remove_all_t<typename ExpressionType::Nested> > {
|
struct traits<MatrixWrapper<ExpressionType> >
|
||||||
|
: public traits<typename remove_all<typename ExpressionType::Nested>::type >
|
||||||
|
{
|
||||||
typedef MatrixXpr XprKind;
|
typedef MatrixXpr XprKind;
|
||||||
// Let's remove NestByRefBit
|
|
||||||
enum {
|
|
||||||
Flags0 = traits<remove_all_t<typename ExpressionType::Nested> >::Flags,
|
|
||||||
LvalueBitFlag = is_lvalue<ExpressionType>::value ? LvalueBit : 0,
|
|
||||||
Flags = (Flags0 & ~(NestByRefBit | LvalueBit)) | LvalueBitFlag
|
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
template<typename ExpressionType>
|
template<typename ExpressionType>
|
||||||
class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> > {
|
class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
typedef MatrixBase<MatrixWrapper<ExpressionType> > Base;
|
typedef MatrixBase<MatrixWrapper<ExpressionType> > Base;
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE(MatrixWrapper)
|
EIGEN_DENSE_PUBLIC_INTERFACE(MatrixWrapper)
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(MatrixWrapper)
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(MatrixWrapper)
|
||||||
typedef internal::remove_all_t<ExpressionType> NestedExpression;
|
|
||||||
|
|
||||||
typedef std::conditional_t<internal::is_lvalue<ExpressionType>::value, Scalar, const Scalar>
|
typedef typename internal::conditional<
|
||||||
ScalarWithConstIfNotLvalue;
|
internal::is_lvalue<ExpressionType>::value,
|
||||||
|
Scalar,
|
||||||
|
const Scalar
|
||||||
|
>::type ScalarWithConstIfNotLvalue;
|
||||||
|
|
||||||
typedef typename internal::ref_selector<ExpressionType>::non_const_type NestedExpressionType;
|
typedef typename internal::nested<ExpressionType>::type NestedExpressionType;
|
||||||
|
|
||||||
using Base::coeffRef;
|
inline MatrixWrapper(const ExpressionType& matrix) : m_expression(matrix) {}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr explicit inline MatrixWrapper(ExpressionType& matrix) : m_expression(matrix) {}
|
inline Index rows() const { return m_expression.rows(); }
|
||||||
|
inline Index cols() const { return m_expression.cols(); }
|
||||||
|
inline Index outerStride() const { return m_expression.outerStride(); }
|
||||||
|
inline Index innerStride() const { return m_expression.innerStride(); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index rows() const noexcept { return m_expression.rows(); }
|
inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
|
||||||
EIGEN_DEVICE_FUNC constexpr Index cols() const noexcept { return m_expression.cols(); }
|
inline const Scalar* data() const { return m_expression.data(); }
|
||||||
EIGEN_DEVICE_FUNC constexpr Index outerStride() const noexcept { return m_expression.outerStride(); }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index innerStride() const noexcept { return m_expression.innerStride(); }
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
|
inline const CoeffReturnType coeff(Index row, Index col) const
|
||||||
EIGEN_DEVICE_FUNC constexpr const Scalar* data() const { return m_expression.data(); }
|
{
|
||||||
|
return m_expression.coeff(row, col);
|
||||||
EIGEN_DEVICE_FUNC inline const Scalar& coeffRef(Index rowId, Index colId) const {
|
|
||||||
return m_expression.derived().coeffRef(rowId, colId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline const Scalar& coeffRef(Index index) const { return m_expression.coeffRef(index); }
|
inline Scalar& coeffRef(Index row, Index col)
|
||||||
|
{
|
||||||
EIGEN_DEVICE_FUNC constexpr const internal::remove_all_t<NestedExpressionType>& nestedExpression() const {
|
return m_expression.const_cast_derived().coeffRef(row, col);
|
||||||
return m_expression;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Forwards the resizing request to the nested expression
|
inline const Scalar& coeffRef(Index row, Index col) const
|
||||||
* \sa DenseBase::resize(Index) */
|
{
|
||||||
EIGEN_DEVICE_FUNC void resize(Index newSize) { m_expression.resize(newSize); }
|
return m_expression.derived().coeffRef(row, col);
|
||||||
/** Forwards the resizing request to the nested expression
|
}
|
||||||
* \sa DenseBase::resize(Index,Index)*/
|
|
||||||
EIGEN_DEVICE_FUNC void resize(Index rows, Index cols) { m_expression.resize(rows, cols); }
|
inline const CoeffReturnType coeff(Index index) const
|
||||||
|
{
|
||||||
|
return m_expression.coeff(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Scalar& coeffRef(Index index)
|
||||||
|
{
|
||||||
|
return m_expression.const_cast_derived().coeffRef(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Scalar& coeffRef(Index index) const
|
||||||
|
{
|
||||||
|
return m_expression.const_cast_derived().coeffRef(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
inline const PacketScalar packet(Index row, Index col) const
|
||||||
|
{
|
||||||
|
return m_expression.template packet<LoadMode>(row, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
inline void writePacket(Index row, Index col, const PacketScalar& x)
|
||||||
|
{
|
||||||
|
m_expression.const_cast_derived().template writePacket<LoadMode>(row, col, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
inline const PacketScalar packet(Index index) const
|
||||||
|
{
|
||||||
|
return m_expression.template packet<LoadMode>(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
inline void writePacket(Index index, const PacketScalar& x)
|
||||||
|
{
|
||||||
|
m_expression.const_cast_derived().template writePacket<LoadMode>(index, x);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
NestedExpressionType m_expression;
|
const NestedExpressionType m_expression;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_ARRAYWRAPPER_H
|
#endif // EIGEN_ARRAYWRAPPER_H
|
||||||
|
|||||||
@@ -5,80 +5,589 @@
|
|||||||
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
|
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_ASSIGN_H
|
#ifndef EIGEN_ASSIGN_H
|
||||||
#define EIGEN_ASSIGN_H
|
#define EIGEN_ASSIGN_H
|
||||||
|
|
||||||
// IWYU pragma: private
|
namespace internal {
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
/***************************************************************************
|
||||||
|
* Part 1 : the logic deciding a strategy for traversal and unrolling *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
template <typename Derived, typename OtherDerived>
|
||||||
|
struct assign_traits
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
DstIsAligned = Derived::Flags & AlignedBit,
|
||||||
|
DstHasDirectAccess = Derived::Flags & DirectAccessBit,
|
||||||
|
SrcIsAligned = OtherDerived::Flags & AlignedBit,
|
||||||
|
JointAlignment = bool(DstIsAligned) && bool(SrcIsAligned) ? Aligned : Unaligned
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum {
|
||||||
|
InnerSize = int(Derived::IsVectorAtCompileTime) ? int(Derived::SizeAtCompileTime)
|
||||||
|
: int(Derived::Flags)&RowMajorBit ? int(Derived::ColsAtCompileTime)
|
||||||
|
: int(Derived::RowsAtCompileTime),
|
||||||
|
InnerMaxSize = int(Derived::IsVectorAtCompileTime) ? int(Derived::MaxSizeAtCompileTime)
|
||||||
|
: int(Derived::Flags)&RowMajorBit ? int(Derived::MaxColsAtCompileTime)
|
||||||
|
: int(Derived::MaxRowsAtCompileTime),
|
||||||
|
MaxSizeAtCompileTime = Derived::SizeAtCompileTime,
|
||||||
|
PacketSize = packet_traits<typename Derived::Scalar>::size
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
StorageOrdersAgree = (int(Derived::IsRowMajor) == int(OtherDerived::IsRowMajor)),
|
||||||
|
MightVectorize = StorageOrdersAgree
|
||||||
|
&& (int(Derived::Flags) & int(OtherDerived::Flags) & ActualPacketAccessBit),
|
||||||
|
MayInnerVectorize = MightVectorize && int(InnerSize)!=Dynamic && int(InnerSize)%int(PacketSize)==0
|
||||||
|
&& int(DstIsAligned) && int(SrcIsAligned),
|
||||||
|
MayLinearize = StorageOrdersAgree && (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit),
|
||||||
|
MayLinearVectorize = MightVectorize && MayLinearize && DstHasDirectAccess
|
||||||
|
&& (DstIsAligned || MaxSizeAtCompileTime == Dynamic),
|
||||||
|
/* If the destination isn't aligned, we have to do runtime checks and we don't unroll,
|
||||||
|
so it's only good for large enough sizes. */
|
||||||
|
MaySliceVectorize = MightVectorize && DstHasDirectAccess
|
||||||
|
&& (int(InnerMaxSize)==Dynamic || int(InnerMaxSize)>=3*PacketSize)
|
||||||
|
/* slice vectorization can be slow, so we only want it if the slices are big, which is
|
||||||
|
indicated by InnerMaxSize rather than InnerSize, think of the case of a dynamic block
|
||||||
|
in a fixed-size matrix */
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Traversal = int(MayInnerVectorize) ? int(InnerVectorizedTraversal)
|
||||||
|
: int(MayLinearVectorize) ? int(LinearVectorizedTraversal)
|
||||||
|
: int(MaySliceVectorize) ? int(SliceVectorizedTraversal)
|
||||||
|
: int(MayLinearize) ? int(LinearTraversal)
|
||||||
|
: int(DefaultTraversal),
|
||||||
|
Vectorized = int(Traversal) == InnerVectorizedTraversal
|
||||||
|
|| int(Traversal) == LinearVectorizedTraversal
|
||||||
|
|| int(Traversal) == SliceVectorizedTraversal
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum {
|
||||||
|
UnrollingLimit = EIGEN_UNROLLING_LIMIT * (Vectorized ? int(PacketSize) : 1),
|
||||||
|
MayUnrollCompletely = int(Derived::SizeAtCompileTime) != Dynamic
|
||||||
|
&& int(OtherDerived::CoeffReadCost) != Dynamic
|
||||||
|
&& int(Derived::SizeAtCompileTime) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit),
|
||||||
|
MayUnrollInner = int(InnerSize) != Dynamic
|
||||||
|
&& int(OtherDerived::CoeffReadCost) != Dynamic
|
||||||
|
&& int(InnerSize) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit)
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
Unrolling = (int(Traversal) == int(InnerVectorizedTraversal) || int(Traversal) == int(DefaultTraversal))
|
||||||
|
? (
|
||||||
|
int(MayUnrollCompletely) ? int(CompleteUnrolling)
|
||||||
|
: int(MayUnrollInner) ? int(InnerUnrolling)
|
||||||
|
: int(NoUnrolling)
|
||||||
|
)
|
||||||
|
: int(Traversal) == int(LinearVectorizedTraversal)
|
||||||
|
? ( bool(MayUnrollCompletely) && bool(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) )
|
||||||
|
: int(Traversal) == int(LinearTraversal)
|
||||||
|
? ( bool(MayUnrollCompletely) ? int(CompleteUnrolling) : int(NoUnrolling) )
|
||||||
|
: int(NoUnrolling)
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef EIGEN_DEBUG_ASSIGN
|
||||||
|
static void debug()
|
||||||
|
{
|
||||||
|
EIGEN_DEBUG_VAR(DstIsAligned)
|
||||||
|
EIGEN_DEBUG_VAR(SrcIsAligned)
|
||||||
|
EIGEN_DEBUG_VAR(JointAlignment)
|
||||||
|
EIGEN_DEBUG_VAR(InnerSize)
|
||||||
|
EIGEN_DEBUG_VAR(InnerMaxSize)
|
||||||
|
EIGEN_DEBUG_VAR(PacketSize)
|
||||||
|
EIGEN_DEBUG_VAR(StorageOrdersAgree)
|
||||||
|
EIGEN_DEBUG_VAR(MightVectorize)
|
||||||
|
EIGEN_DEBUG_VAR(MayLinearize)
|
||||||
|
EIGEN_DEBUG_VAR(MayInnerVectorize)
|
||||||
|
EIGEN_DEBUG_VAR(MayLinearVectorize)
|
||||||
|
EIGEN_DEBUG_VAR(MaySliceVectorize)
|
||||||
|
EIGEN_DEBUG_VAR(Traversal)
|
||||||
|
EIGEN_DEBUG_VAR(UnrollingLimit)
|
||||||
|
EIGEN_DEBUG_VAR(MayUnrollCompletely)
|
||||||
|
EIGEN_DEBUG_VAR(MayUnrollInner)
|
||||||
|
EIGEN_DEBUG_VAR(Unrolling)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* Part 2 : meta-unrollers
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/************************
|
||||||
|
*** Default traversal ***
|
||||||
|
************************/
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2, int Index, int Stop>
|
||||||
|
struct assign_DefaultTraversal_CompleteUnrolling
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
outer = Index / Derived1::InnerSizeAtCompileTime,
|
||||||
|
inner = Index % Derived1::InnerSizeAtCompileTime
|
||||||
|
};
|
||||||
|
|
||||||
|
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
||||||
|
{
|
||||||
|
dst.copyCoeffByOuterInner(outer, inner, src);
|
||||||
|
assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2, int Stop>
|
||||||
|
struct assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
|
||||||
|
{
|
||||||
|
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2, int Index, int Stop>
|
||||||
|
struct assign_DefaultTraversal_InnerUnrolling
|
||||||
|
{
|
||||||
|
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src, int outer)
|
||||||
|
{
|
||||||
|
dst.copyCoeffByOuterInner(outer, Index, src);
|
||||||
|
assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src, outer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2, int Stop>
|
||||||
|
struct assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Stop, Stop>
|
||||||
|
{
|
||||||
|
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &, int) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/***********************
|
||||||
|
*** Linear traversal ***
|
||||||
|
***********************/
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2, int Index, int Stop>
|
||||||
|
struct assign_LinearTraversal_CompleteUnrolling
|
||||||
|
{
|
||||||
|
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
||||||
|
{
|
||||||
|
dst.copyCoeff(Index, src);
|
||||||
|
assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2, int Stop>
|
||||||
|
struct assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
|
||||||
|
{
|
||||||
|
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**************************
|
||||||
|
*** Inner vectorization ***
|
||||||
|
**************************/
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2, int Index, int Stop>
|
||||||
|
struct assign_innervec_CompleteUnrolling
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
outer = Index / Derived1::InnerSizeAtCompileTime,
|
||||||
|
inner = Index % Derived1::InnerSizeAtCompileTime,
|
||||||
|
JointAlignment = assign_traits<Derived1,Derived2>::JointAlignment
|
||||||
|
};
|
||||||
|
|
||||||
|
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
||||||
|
{
|
||||||
|
dst.template copyPacketByOuterInner<Derived2, Aligned, JointAlignment>(outer, inner, src);
|
||||||
|
assign_innervec_CompleteUnrolling<Derived1, Derived2,
|
||||||
|
Index+packet_traits<typename Derived1::Scalar>::size, Stop>::run(dst, src);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2, int Stop>
|
||||||
|
struct assign_innervec_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
|
||||||
|
{
|
||||||
|
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2, int Index, int Stop>
|
||||||
|
struct assign_innervec_InnerUnrolling
|
||||||
|
{
|
||||||
|
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src, int outer)
|
||||||
|
{
|
||||||
|
dst.template copyPacketByOuterInner<Derived2, Aligned, Aligned>(outer, Index, src);
|
||||||
|
assign_innervec_InnerUnrolling<Derived1, Derived2,
|
||||||
|
Index+packet_traits<typename Derived1::Scalar>::size, Stop>::run(dst, src, outer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2, int Stop>
|
||||||
|
struct assign_innervec_InnerUnrolling<Derived1, Derived2, Stop, Stop>
|
||||||
|
{
|
||||||
|
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &, int) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* Part 3 : implementation of all cases
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2,
|
||||||
|
int Traversal = assign_traits<Derived1, Derived2>::Traversal,
|
||||||
|
int Unrolling = assign_traits<Derived1, Derived2>::Unrolling>
|
||||||
|
struct assign_impl;
|
||||||
|
|
||||||
|
/************************
|
||||||
|
*** Default traversal ***
|
||||||
|
************************/
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2, int Unrolling>
|
||||||
|
struct assign_impl<Derived1, Derived2, InvalidTraversal, Unrolling>
|
||||||
|
{
|
||||||
|
inline static void run(Derived1 &, const Derived2 &) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2>
|
||||||
|
struct assign_impl<Derived1, Derived2, DefaultTraversal, NoUnrolling>
|
||||||
|
{
|
||||||
|
typedef typename Derived1::Index Index;
|
||||||
|
inline static void run(Derived1 &dst, const Derived2 &src)
|
||||||
|
{
|
||||||
|
const Index innerSize = dst.innerSize();
|
||||||
|
const Index outerSize = dst.outerSize();
|
||||||
|
for(Index outer = 0; outer < outerSize; ++outer)
|
||||||
|
for(Index inner = 0; inner < innerSize; ++inner)
|
||||||
|
dst.copyCoeffByOuterInner(outer, inner, src);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2>
|
||||||
|
struct assign_impl<Derived1, Derived2, DefaultTraversal, CompleteUnrolling>
|
||||||
|
{
|
||||||
|
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
||||||
|
{
|
||||||
|
assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
|
||||||
|
::run(dst, src);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2>
|
||||||
|
struct assign_impl<Derived1, Derived2, DefaultTraversal, InnerUnrolling>
|
||||||
|
{
|
||||||
|
typedef typename Derived1::Index Index;
|
||||||
|
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
||||||
|
{
|
||||||
|
const Index outerSize = dst.outerSize();
|
||||||
|
for(Index outer = 0; outer < outerSize; ++outer)
|
||||||
|
assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, 0, Derived1::InnerSizeAtCompileTime>
|
||||||
|
::run(dst, src, outer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/***********************
|
||||||
|
*** Linear traversal ***
|
||||||
|
***********************/
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2>
|
||||||
|
struct assign_impl<Derived1, Derived2, LinearTraversal, NoUnrolling>
|
||||||
|
{
|
||||||
|
typedef typename Derived1::Index Index;
|
||||||
|
inline static void run(Derived1 &dst, const Derived2 &src)
|
||||||
|
{
|
||||||
|
const Index size = dst.size();
|
||||||
|
for(Index i = 0; i < size; ++i)
|
||||||
|
dst.copyCoeff(i, src);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2>
|
||||||
|
struct assign_impl<Derived1, Derived2, LinearTraversal, CompleteUnrolling>
|
||||||
|
{
|
||||||
|
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
||||||
|
{
|
||||||
|
assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
|
||||||
|
::run(dst, src);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**************************
|
||||||
|
*** Inner vectorization ***
|
||||||
|
**************************/
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2>
|
||||||
|
struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, NoUnrolling>
|
||||||
|
{
|
||||||
|
typedef typename Derived1::Index Index;
|
||||||
|
inline static void run(Derived1 &dst, const Derived2 &src)
|
||||||
|
{
|
||||||
|
const Index innerSize = dst.innerSize();
|
||||||
|
const Index outerSize = dst.outerSize();
|
||||||
|
const Index packetSize = packet_traits<typename Derived1::Scalar>::size;
|
||||||
|
for(Index outer = 0; outer < outerSize; ++outer)
|
||||||
|
for(Index inner = 0; inner < innerSize; inner+=packetSize)
|
||||||
|
dst.template copyPacketByOuterInner<Derived2, Aligned, Aligned>(outer, inner, src);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2>
|
||||||
|
struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, CompleteUnrolling>
|
||||||
|
{
|
||||||
|
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
||||||
|
{
|
||||||
|
assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
|
||||||
|
::run(dst, src);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2>
|
||||||
|
struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, InnerUnrolling>
|
||||||
|
{
|
||||||
|
typedef typename Derived1::Index Index;
|
||||||
|
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
||||||
|
{
|
||||||
|
const Index outerSize = dst.outerSize();
|
||||||
|
for(Index outer = 0; outer < outerSize; ++outer)
|
||||||
|
assign_innervec_InnerUnrolling<Derived1, Derived2, 0, Derived1::InnerSizeAtCompileTime>
|
||||||
|
::run(dst, src, outer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/***************************
|
||||||
|
*** Linear vectorization ***
|
||||||
|
***************************/
|
||||||
|
|
||||||
|
template <bool IsAligned = false>
|
||||||
|
struct unaligned_assign_impl
|
||||||
|
{
|
||||||
|
template <typename Derived, typename OtherDerived>
|
||||||
|
static EIGEN_STRONG_INLINE void run(const Derived&, OtherDerived&, typename Derived::Index, typename Derived::Index) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct unaligned_assign_impl<false>
|
||||||
|
{
|
||||||
|
// MSVC must not inline this functions. If it does, it fails to optimize the
|
||||||
|
// packet access path.
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
template <typename Derived, typename OtherDerived>
|
||||||
|
static EIGEN_DONT_INLINE void run(const Derived& src, OtherDerived& dst, typename Derived::Index start, typename Derived::Index end)
|
||||||
|
#else
|
||||||
|
template <typename Derived, typename OtherDerived>
|
||||||
|
static EIGEN_STRONG_INLINE void run(const Derived& src, OtherDerived& dst, typename Derived::Index start, typename Derived::Index end)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
for (typename Derived::Index index = start; index < end; ++index)
|
||||||
|
dst.copyCoeff(index, src);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2>
|
||||||
|
struct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, NoUnrolling>
|
||||||
|
{
|
||||||
|
typedef typename Derived1::Index Index;
|
||||||
|
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
||||||
|
{
|
||||||
|
const Index size = dst.size();
|
||||||
|
typedef packet_traits<typename Derived1::Scalar> PacketTraits;
|
||||||
|
enum {
|
||||||
|
packetSize = PacketTraits::size,
|
||||||
|
dstAlignment = PacketTraits::AlignedOnScalar ? Aligned : int(assign_traits<Derived1,Derived2>::DstIsAligned) ,
|
||||||
|
srcAlignment = assign_traits<Derived1,Derived2>::JointAlignment
|
||||||
|
};
|
||||||
|
const Index alignedStart = assign_traits<Derived1,Derived2>::DstIsAligned ? 0
|
||||||
|
: first_aligned(&dst.coeffRef(0), size);
|
||||||
|
const Index alignedEnd = alignedStart + ((size-alignedStart)/packetSize)*packetSize;
|
||||||
|
|
||||||
|
unaligned_assign_impl<assign_traits<Derived1,Derived2>::DstIsAligned!=0>::run(src,dst,0,alignedStart);
|
||||||
|
|
||||||
|
for(Index index = alignedStart; index < alignedEnd; index += packetSize)
|
||||||
|
{
|
||||||
|
dst.template copyPacket<Derived2, dstAlignment, srcAlignment>(index, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
unaligned_assign_impl<>::run(src,dst,alignedEnd,size);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2>
|
||||||
|
struct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, CompleteUnrolling>
|
||||||
|
{
|
||||||
|
typedef typename Derived1::Index Index;
|
||||||
|
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
||||||
|
{
|
||||||
|
enum { size = Derived1::SizeAtCompileTime,
|
||||||
|
packetSize = packet_traits<typename Derived1::Scalar>::size,
|
||||||
|
alignedSize = (size/packetSize)*packetSize };
|
||||||
|
|
||||||
|
assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, alignedSize>::run(dst, src);
|
||||||
|
assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, alignedSize, size>::run(dst, src);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**************************
|
||||||
|
*** Slice vectorization ***
|
||||||
|
***************************/
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2>
|
||||||
|
struct assign_impl<Derived1, Derived2, SliceVectorizedTraversal, NoUnrolling>
|
||||||
|
{
|
||||||
|
typedef typename Derived1::Index Index;
|
||||||
|
inline static void run(Derived1 &dst, const Derived2 &src)
|
||||||
|
{
|
||||||
|
typedef packet_traits<typename Derived1::Scalar> PacketTraits;
|
||||||
|
enum {
|
||||||
|
packetSize = PacketTraits::size,
|
||||||
|
alignable = PacketTraits::AlignedOnScalar,
|
||||||
|
dstAlignment = alignable ? Aligned : int(assign_traits<Derived1,Derived2>::DstIsAligned) ,
|
||||||
|
srcAlignment = assign_traits<Derived1,Derived2>::JointAlignment
|
||||||
|
};
|
||||||
|
const Index packetAlignedMask = packetSize - 1;
|
||||||
|
const Index innerSize = dst.innerSize();
|
||||||
|
const Index outerSize = dst.outerSize();
|
||||||
|
const Index alignedStep = alignable ? (packetSize - dst.outerStride() % packetSize) & packetAlignedMask : 0;
|
||||||
|
Index alignedStart = ((!alignable) || assign_traits<Derived1,Derived2>::DstIsAligned) ? 0
|
||||||
|
: first_aligned(&dst.coeffRef(0,0), innerSize);
|
||||||
|
|
||||||
|
for(Index outer = 0; outer < outerSize; ++outer)
|
||||||
|
{
|
||||||
|
const Index alignedEnd = alignedStart + ((innerSize-alignedStart) & ~packetAlignedMask);
|
||||||
|
// do the non-vectorizable part of the assignment
|
||||||
|
for(Index inner = 0; inner<alignedStart ; ++inner)
|
||||||
|
dst.copyCoeffByOuterInner(outer, inner, src);
|
||||||
|
|
||||||
|
// do the vectorizable part of the assignment
|
||||||
|
for(Index inner = alignedStart; inner<alignedEnd; inner+=packetSize)
|
||||||
|
dst.template copyPacketByOuterInner<Derived2, dstAlignment, Unaligned>(outer, inner, src);
|
||||||
|
|
||||||
|
// do the non-vectorizable part of the assignment
|
||||||
|
for(Index inner = alignedEnd; inner<innerSize ; ++inner)
|
||||||
|
dst.copyCoeffByOuterInner(outer, inner, src);
|
||||||
|
|
||||||
|
alignedStart = std::min<Index>((alignedStart+alignedStep)%packetSize, innerSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace internal
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* Part 4 : implementation of DenseBase methods
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::lazyAssign(
|
EIGEN_STRONG_INLINE Derived& DenseBase<Derived>
|
||||||
const DenseBase<OtherDerived>& other) {
|
::lazyAssign(const DenseBase<OtherDerived>& other)
|
||||||
enum { SameType = internal::is_same<typename Derived::Scalar, typename OtherDerived::Scalar>::value };
|
{
|
||||||
|
enum{
|
||||||
|
SameType = internal::is_same<typename Derived::Scalar,typename OtherDerived::Scalar>::value
|
||||||
|
};
|
||||||
|
|
||||||
EIGEN_STATIC_ASSERT_LVALUE(Derived)
|
EIGEN_STATIC_ASSERT_LVALUE(Derived)
|
||||||
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived)
|
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived)
|
||||||
EIGEN_STATIC_ASSERT(
|
EIGEN_STATIC_ASSERT(SameType,YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||||
SameType,
|
|
||||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
|
||||||
|
|
||||||
|
#ifdef EIGEN_DEBUG_ASSIGN
|
||||||
|
internal::assign_traits<Derived, OtherDerived>::debug();
|
||||||
|
#endif
|
||||||
eigen_assert(rows() == other.rows() && cols() == other.cols());
|
eigen_assert(rows() == other.rows() && cols() == other.cols());
|
||||||
internal::call_assignment_no_alias(derived(), other.derived());
|
internal::assign_impl<Derived, OtherDerived, int(SameType) ? int(internal::assign_traits<Derived, OtherDerived>::Traversal)
|
||||||
|
: int(InvalidTraversal)>::run(derived(),other.derived());
|
||||||
|
#ifndef EIGEN_NO_DEBUG
|
||||||
|
checkTransposeAliasing(other.derived());
|
||||||
|
#endif
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template<typename Derived, typename OtherDerived,
|
||||||
|
bool EvalBeforeAssigning = (int(OtherDerived::Flags) & EvalBeforeAssigningBit) != 0,
|
||||||
|
bool NeedToTranspose = Derived::IsVectorAtCompileTime
|
||||||
|
&& OtherDerived::IsVectorAtCompileTime
|
||||||
|
&& ((int(Derived::RowsAtCompileTime) == 1 && int(OtherDerived::ColsAtCompileTime) == 1)
|
||||||
|
| // FIXME | instead of || to please GCC 4.4.0 stupid warning "suggest parentheses around &&".
|
||||||
|
// revert to || as soon as not needed anymore.
|
||||||
|
(int(Derived::ColsAtCompileTime) == 1 && int(OtherDerived::RowsAtCompileTime) == 1))
|
||||||
|
&& int(Derived::SizeAtCompileTime) != 1>
|
||||||
|
struct assign_selector;
|
||||||
|
|
||||||
|
template<typename Derived, typename OtherDerived>
|
||||||
|
struct assign_selector<Derived,OtherDerived,false,false> {
|
||||||
|
EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); }
|
||||||
|
};
|
||||||
|
template<typename Derived, typename OtherDerived>
|
||||||
|
struct assign_selector<Derived,OtherDerived,true,false> {
|
||||||
|
EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.eval()); }
|
||||||
|
};
|
||||||
|
template<typename Derived, typename OtherDerived>
|
||||||
|
struct assign_selector<Derived,OtherDerived,false,true> {
|
||||||
|
EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); }
|
||||||
|
};
|
||||||
|
template<typename Derived, typename OtherDerived>
|
||||||
|
struct assign_selector<Derived,OtherDerived,true,true> {
|
||||||
|
EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose().eval()); }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace internal
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
template<typename OtherDerived>
|
||||||
|
EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator=(const DenseBase<OtherDerived>& other)
|
||||||
|
{
|
||||||
|
return internal::assign_selector<Derived,OtherDerived>::run(derived(), other.derived());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator=(const DenseBase& other)
|
||||||
|
{
|
||||||
|
return internal::assign_selector<Derived,Derived>::run(derived(), other.derived());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const MatrixBase& other)
|
||||||
|
{
|
||||||
|
return internal::assign_selector<Derived,Derived>::run(derived(), other.derived());
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template <typename OtherDerived>
|
template <typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator=(
|
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const DenseBase<OtherDerived>& other)
|
||||||
const DenseBase<OtherDerived>& other) {
|
{
|
||||||
internal::call_assignment(derived(), other.derived());
|
return internal::assign_selector<Derived,OtherDerived>::run(derived(), other.derived());
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Derived>
|
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator=(const DenseBase& other) {
|
|
||||||
internal::call_assignment(derived(), other.derived());
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Derived>
|
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const MatrixBase& other) {
|
|
||||||
internal::call_assignment(derived(), other.derived());
|
|
||||||
return derived();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template <typename OtherDerived>
|
template <typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(
|
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const EigenBase<OtherDerived>& other)
|
||||||
const DenseBase<OtherDerived>& other) {
|
{
|
||||||
internal::call_assignment(derived(), other.derived());
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Derived>
|
|
||||||
template <typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(
|
|
||||||
const EigenBase<OtherDerived>& other) {
|
|
||||||
internal::call_assignment(derived(), other.derived());
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Derived>
|
|
||||||
template <typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(
|
|
||||||
const ReturnByValue<OtherDerived>& other) {
|
|
||||||
other.derived().evalTo(derived());
|
other.derived().evalTo(derived());
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace Eigen
|
template<typename Derived>
|
||||||
|
template<typename OtherDerived>
|
||||||
|
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
|
||||||
|
{
|
||||||
|
other.evalTo(derived());
|
||||||
|
return derived();
|
||||||
|
}
|
||||||
|
|
||||||
#endif // EIGEN_ASSIGN_H
|
#endif // EIGEN_ASSIGN_H
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,301 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 https://mozilla.org/MPL/2.0/.
|
|
||||||
*
|
|
||||||
* Assign_AOCL.h - AOCL Vectorized Math Dispatch Layer for Eigen
|
|
||||||
*
|
|
||||||
* Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* ------------
|
|
||||||
* This file implements a high-performance dispatch layer that automatically
|
|
||||||
* routes Eigen's element-wise mathematical operations to AMD Optimizing CPU
|
|
||||||
* Libraries (AOCL) Vector Math Library (VML) functions when beneficial for
|
|
||||||
* performance.
|
|
||||||
*
|
|
||||||
* The dispatch system uses C++ template specialization to intercept Eigen's
|
|
||||||
* assignment operations and redirect them to AOCL's VRDA functions, which
|
|
||||||
* provide optimized implementations for AMD Zen architectures.
|
|
||||||
*
|
|
||||||
* Key Features:
|
|
||||||
* -------------
|
|
||||||
* 1. Automatic Dispatch: Seamlessly routes supported operations to AOCL without
|
|
||||||
* requiring code changes in user applications
|
|
||||||
*
|
|
||||||
* 2. Performance Optimization: Uses AOCL VRDA functions optimized for Zen
|
|
||||||
* family processors with automatic SIMD instruction selection (AVX2, AVX-512)
|
|
||||||
*
|
|
||||||
* 3. Threshold-Based Activation: Only activates for vectors larger than
|
|
||||||
* EIGEN_AOCL_VML_THRESHOLD (default: 128 elements) to avoid overhead on
|
|
||||||
* small vectors
|
|
||||||
*
|
|
||||||
* 4. Precision-Specific Handling:
|
|
||||||
* - Double precision: AOCL VRDA vectorized functions
|
|
||||||
* - Single precision: Scalar fallback (preserves correctness)
|
|
||||||
*
|
|
||||||
* 5. Memory Layout Compatibility: Ensures direct memory access and compatible
|
|
||||||
* storage orders between source and destination for optimal performance
|
|
||||||
*
|
|
||||||
* Supported Operations:
|
|
||||||
* ---------------------
|
|
||||||
* UNARY OPERATIONS (vector → vector):
|
|
||||||
* - Transcendental: exp(), sin(), cos(), sqrt(), log(), log10(), log2()
|
|
||||||
*
|
|
||||||
* BINARY OPERATIONS (vector op vector → vector):
|
|
||||||
* - Arithmetic: +, *, pow()
|
|
||||||
*
|
|
||||||
* Template Specialization Mechanism:
|
|
||||||
* -----------------------------------
|
|
||||||
* The system works by specializing Eigen's Assignment template for:
|
|
||||||
* 1. CwiseUnaryOp with scalar_*_op functors (unary operations)
|
|
||||||
* 2. CwiseBinaryOp with scalar_*_op functors (binary operations)
|
|
||||||
* 3. Dense2Dense assignment context with AOCL-compatible traits
|
|
||||||
*
|
|
||||||
* Dispatch conditions (all must be true):
|
|
||||||
* - Source and destination have DirectAccessBit (contiguous memory)
|
|
||||||
* - Compatible storage orders (both row-major or both column-major)
|
|
||||||
* - Vector size ≥ EIGEN_AOCL_VML_THRESHOLD or Dynamic size
|
|
||||||
* - Supported data type (currently double precision for VRDA)
|
|
||||||
*
|
|
||||||
* Integration Example:
|
|
||||||
* --------------------
|
|
||||||
* // Standard Eigen code - no changes required
|
|
||||||
* VectorXd x = VectorXd::Random(10000);
|
|
||||||
* VectorXd y = VectorXd::Random(10000);
|
|
||||||
* VectorXd result;
|
|
||||||
*
|
|
||||||
* // These operations are automatically dispatched to AOCL:
|
|
||||||
* result = x.array().exp(); // → amd_vrda_exp()
|
|
||||||
* result = x.array().sin(); // → amd_vrda_sin()
|
|
||||||
* result = x.array() + y.array(); // → amd_vrda_add()
|
|
||||||
* result = x.array().pow(y.array()); // → amd_vrda_pow()
|
|
||||||
*
|
|
||||||
* Configuration:
|
|
||||||
* --------------
|
|
||||||
* Required preprocessor definitions:
|
|
||||||
* - EIGEN_USE_AOCL_ALL or EIGEN_USE_AOCL_MT: Enable AOCL integration
|
|
||||||
* - EIGEN_USE_AOCL_VML: Enable Vector Math Library dispatch
|
|
||||||
*
|
|
||||||
* Compilation Requirements:
|
|
||||||
* -------------------------
|
|
||||||
* Include paths:
|
|
||||||
* - AOCL headers: -I${AOCL_ROOT}/include
|
|
||||||
* - Eigen headers: -I/path/to/eigen
|
|
||||||
*
|
|
||||||
* Link libraries:
|
|
||||||
* - AOCL MathLib: -lamdlibm
|
|
||||||
* - Standard math: -lm
|
|
||||||
*
|
|
||||||
* Compiler flags:
|
|
||||||
* - Optimization: -O3 (required for inlining)
|
|
||||||
* - Architecture: -march=znver5 or -march=native
|
|
||||||
* - Vectorization: -mfma -mavx512f (if supported)
|
|
||||||
*
|
|
||||||
* Platform Support:
|
|
||||||
* ------------------
|
|
||||||
* - Primary: Linux x86_64 with AMD Zen family processors
|
|
||||||
* - Compilers: GCC 8+, Clang 10+, AOCC (recommended)
|
|
||||||
* - AOCL Version: 4.0+ (with VRDA support)
|
|
||||||
*
|
|
||||||
* Error Handling:
|
|
||||||
* ---------------
|
|
||||||
* - Graceful fallback to scalar operations for unsupported configurations
|
|
||||||
* - Compile-time detection of AOCL availability
|
|
||||||
* - Runtime size and alignment validation with eigen_assert()
|
|
||||||
*
|
|
||||||
* Developer:
|
|
||||||
* ----------
|
|
||||||
* Name: Sharad Saurabh Bhaskar
|
|
||||||
* Email: shbhaska@amd.com
|
|
||||||
* Organization: Advanced Micro Devices, Inc.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef EIGEN_ASSIGN_AOCL_H
|
|
||||||
#define EIGEN_ASSIGN_AOCL_H
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
// Traits for unary operations.
|
|
||||||
template <typename Dst, typename Src> class aocl_assign_traits {
|
|
||||||
private:
|
|
||||||
enum {
|
|
||||||
DstHasDirectAccess = !!(Dst::Flags & DirectAccessBit),
|
|
||||||
SrcHasDirectAccess = !!(Src::Flags & DirectAccessBit),
|
|
||||||
StorageOrdersAgree = (int(Dst::IsRowMajor) == int(Src::IsRowMajor)),
|
|
||||||
InnerSize = Dst::IsVectorAtCompileTime ? int(Dst::SizeAtCompileTime)
|
|
||||||
: (Dst::Flags & RowMajorBit) ? int(Dst::ColsAtCompileTime)
|
|
||||||
: int(Dst::RowsAtCompileTime),
|
|
||||||
LargeEnough =
|
|
||||||
(InnerSize == Dynamic) || (InnerSize >= EIGEN_AOCL_VML_THRESHOLD)
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum {
|
|
||||||
EnableAoclVML = DstHasDirectAccess && SrcHasDirectAccess &&
|
|
||||||
StorageOrdersAgree && LargeEnough,
|
|
||||||
Traversal = LinearTraversal
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Traits for binary operations (e.g., add, pow).
|
|
||||||
template <typename Dst, typename Lhs, typename Rhs>
|
|
||||||
class aocl_assign_binary_traits {
|
|
||||||
private:
|
|
||||||
enum {
|
|
||||||
DstHasDirectAccess = !!(Dst::Flags & DirectAccessBit),
|
|
||||||
LhsHasDirectAccess = !!(Lhs::Flags & DirectAccessBit),
|
|
||||||
RhsHasDirectAccess = !!(Rhs::Flags & DirectAccessBit),
|
|
||||||
StorageOrdersAgree = (int(Dst::IsRowMajor) == int(Lhs::IsRowMajor)) &&
|
|
||||||
(int(Dst::IsRowMajor) == int(Rhs::IsRowMajor)),
|
|
||||||
InnerSize = Dst::IsVectorAtCompileTime ? int(Dst::SizeAtCompileTime)
|
|
||||||
: (Dst::Flags & RowMajorBit) ? int(Dst::ColsAtCompileTime)
|
|
||||||
: int(Dst::RowsAtCompileTime),
|
|
||||||
LargeEnough =
|
|
||||||
(InnerSize == Dynamic) || (InnerSize >= EIGEN_AOCL_VML_THRESHOLD)
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum {
|
|
||||||
EnableAoclVML = DstHasDirectAccess && LhsHasDirectAccess &&
|
|
||||||
RhsHasDirectAccess && StorageOrdersAgree && LargeEnough
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Unary operation dispatch for float (scalar fallback).
|
|
||||||
#define EIGEN_AOCL_VML_UNARY_CALL_FLOAT(EIGENOP) \
|
|
||||||
template <typename DstXprType, typename SrcXprNested> \
|
|
||||||
struct Assignment< \
|
|
||||||
DstXprType, CwiseUnaryOp<scalar_##EIGENOP##_op<float>, SrcXprNested>, \
|
|
||||||
assign_op<float, float>, Dense2Dense, \
|
|
||||||
std::enable_if_t< \
|
|
||||||
aocl_assign_traits<DstXprType, SrcXprNested>::EnableAoclVML>> { \
|
|
||||||
typedef CwiseUnaryOp<scalar_##EIGENOP##_op<float>, SrcXprNested> \
|
|
||||||
SrcXprType; \
|
|
||||||
static void run(DstXprType &dst, const SrcXprType &src, \
|
|
||||||
const assign_op<float, float> &) { \
|
|
||||||
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols()); \
|
|
||||||
Eigen::Index n = dst.size(); \
|
|
||||||
if (n <= 0) \
|
|
||||||
return; \
|
|
||||||
const float *input = \
|
|
||||||
reinterpret_cast<const float *>(src.nestedExpression().data()); \
|
|
||||||
float *output = reinterpret_cast<float *>(dst.data()); \
|
|
||||||
for (Eigen::Index i = 0; i < n; ++i) { \
|
|
||||||
output[i] = std::EIGENOP(input[i]); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
};
|
|
||||||
|
|
||||||
// Unary operation dispatch for double (AOCL vectorized).
|
|
||||||
#define EIGEN_AOCL_VML_UNARY_CALL_DOUBLE(EIGENOP, AOCLOP) \
|
|
||||||
template <typename DstXprType, typename SrcXprNested> \
|
|
||||||
struct Assignment< \
|
|
||||||
DstXprType, CwiseUnaryOp<scalar_##EIGENOP##_op<double>, SrcXprNested>, \
|
|
||||||
assign_op<double, double>, Dense2Dense, \
|
|
||||||
std::enable_if_t< \
|
|
||||||
aocl_assign_traits<DstXprType, SrcXprNested>::EnableAoclVML>> { \
|
|
||||||
typedef CwiseUnaryOp<scalar_##EIGENOP##_op<double>, SrcXprNested> \
|
|
||||||
SrcXprType; \
|
|
||||||
static void run(DstXprType &dst, const SrcXprType &src, \
|
|
||||||
const assign_op<double, double> &) { \
|
|
||||||
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols()); \
|
|
||||||
Eigen::Index n = dst.size(); \
|
|
||||||
eigen_assert(n <= INT_MAX && "AOCL does not support arrays larger than INT_MAX"); \
|
|
||||||
if (n <= 0) \
|
|
||||||
return; \
|
|
||||||
const double *input = \
|
|
||||||
reinterpret_cast<const double *>(src.nestedExpression().data()); \
|
|
||||||
double *output = reinterpret_cast<double *>(dst.data()); \
|
|
||||||
int aocl_n = internal::convert_index<int>(n); \
|
|
||||||
AOCLOP(aocl_n, const_cast<double *>(input), output); \
|
|
||||||
} \
|
|
||||||
};
|
|
||||||
|
|
||||||
// Instantiate unary calls for float (scalar).
|
|
||||||
// EIGEN_AOCL_VML_UNARY_CALL_FLOAT(exp)
|
|
||||||
|
|
||||||
// Instantiate unary calls for double (AOCL vectorized).
|
|
||||||
EIGEN_AOCL_VML_UNARY_CALL_DOUBLE(exp2, amd_vrda_exp2)
|
|
||||||
EIGEN_AOCL_VML_UNARY_CALL_DOUBLE(exp, amd_vrda_exp)
|
|
||||||
EIGEN_AOCL_VML_UNARY_CALL_DOUBLE(sin, amd_vrda_sin)
|
|
||||||
EIGEN_AOCL_VML_UNARY_CALL_DOUBLE(cos, amd_vrda_cos)
|
|
||||||
EIGEN_AOCL_VML_UNARY_CALL_DOUBLE(sqrt, amd_vrda_sqrt)
|
|
||||||
EIGEN_AOCL_VML_UNARY_CALL_DOUBLE(cbrt, amd_vrda_cbrt)
|
|
||||||
EIGEN_AOCL_VML_UNARY_CALL_DOUBLE(abs, amd_vrda_fabs)
|
|
||||||
EIGEN_AOCL_VML_UNARY_CALL_DOUBLE(log, amd_vrda_log)
|
|
||||||
EIGEN_AOCL_VML_UNARY_CALL_DOUBLE(log10, amd_vrda_log10)
|
|
||||||
EIGEN_AOCL_VML_UNARY_CALL_DOUBLE(log2, amd_vrda_log2)
|
|
||||||
|
|
||||||
// Binary operation dispatch for float (scalar fallback).
|
|
||||||
#define EIGEN_AOCL_VML_BINARY_CALL_FLOAT(EIGENOP, STDFUNC) \
|
|
||||||
template <typename DstXprType, typename LhsXprNested, typename RhsXprNested> \
|
|
||||||
struct Assignment< \
|
|
||||||
DstXprType, \
|
|
||||||
CwiseBinaryOp<scalar_##EIGENOP##_op<float, float>, LhsXprNested, \
|
|
||||||
RhsXprNested>, \
|
|
||||||
assign_op<float, float>, Dense2Dense, \
|
|
||||||
std::enable_if_t<aocl_assign_binary_traits< \
|
|
||||||
DstXprType, LhsXprNested, RhsXprNested>::EnableAoclVML>> { \
|
|
||||||
typedef CwiseBinaryOp<scalar_##EIGENOP##_op<float, float>, LhsXprNested, \
|
|
||||||
RhsXprNested> \
|
|
||||||
SrcXprType; \
|
|
||||||
static void run(DstXprType &dst, const SrcXprType &src, \
|
|
||||||
const assign_op<float, float> &) { \
|
|
||||||
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols()); \
|
|
||||||
Eigen::Index n = dst.size(); \
|
|
||||||
if (n <= 0) \
|
|
||||||
return; \
|
|
||||||
const float *lhs = reinterpret_cast<const float *>(src.lhs().data()); \
|
|
||||||
const float *rhs = reinterpret_cast<const float *>(src.rhs().data()); \
|
|
||||||
float *output = reinterpret_cast<float *>(dst.data()); \
|
|
||||||
for (Eigen::Index i = 0; i < n; ++i) { \
|
|
||||||
output[i] = STDFUNC(lhs[i], rhs[i]); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
};
|
|
||||||
|
|
||||||
// Binary operation dispatch for double (AOCL vectorized).
|
|
||||||
#define EIGEN_AOCL_VML_BINARY_CALL_DOUBLE(EIGENOP, AOCLOP) \
|
|
||||||
template <typename DstXprType, typename LhsXprNested, typename RhsXprNested> \
|
|
||||||
struct Assignment< \
|
|
||||||
DstXprType, \
|
|
||||||
CwiseBinaryOp<scalar_##EIGENOP##_op<double, double>, LhsXprNested, \
|
|
||||||
RhsXprNested>, \
|
|
||||||
assign_op<double, double>, Dense2Dense, \
|
|
||||||
std::enable_if_t<aocl_assign_binary_traits< \
|
|
||||||
DstXprType, LhsXprNested, RhsXprNested>::EnableAoclVML>> { \
|
|
||||||
typedef CwiseBinaryOp<scalar_##EIGENOP##_op<double, double>, LhsXprNested, \
|
|
||||||
RhsXprNested> \
|
|
||||||
SrcXprType; \
|
|
||||||
static void run(DstXprType &dst, const SrcXprType &src, \
|
|
||||||
const assign_op<double, double> &) { \
|
|
||||||
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols()); \
|
|
||||||
Eigen::Index n = dst.size(); \
|
|
||||||
eigen_assert(n <= INT_MAX && "AOCL does not support arrays larger than INT_MAX"); \
|
|
||||||
if (n <= 0) \
|
|
||||||
return; \
|
|
||||||
const double *lhs = reinterpret_cast<const double *>(src.lhs().data()); \
|
|
||||||
const double *rhs = reinterpret_cast<const double *>(src.rhs().data()); \
|
|
||||||
double *output = reinterpret_cast<double *>(dst.data()); \
|
|
||||||
int aocl_n = internal::convert_index<int>(n); \
|
|
||||||
AOCLOP(aocl_n, const_cast<double *>(lhs), const_cast<double *>(rhs), output); \
|
|
||||||
} \
|
|
||||||
};
|
|
||||||
|
|
||||||
// Instantiate binary calls for float (scalar).
|
|
||||||
// EIGEN_AOCL_VML_BINARY_CALL_FLOAT(sum, std::plus<float>) // Using
|
|
||||||
// scalar_sum_op for addition EIGEN_AOCL_VML_BINARY_CALL_FLOAT(pow, std::pow)
|
|
||||||
|
|
||||||
// Instantiate binary calls for double (AOCL vectorized).
|
|
||||||
EIGEN_AOCL_VML_BINARY_CALL_DOUBLE(sum, amd_vrda_add) // Using scalar_sum_op for addition
|
|
||||||
EIGEN_AOCL_VML_BINARY_CALL_DOUBLE(pow, amd_vrda_pow)
|
|
||||||
EIGEN_AOCL_VML_BINARY_CALL_DOUBLE(max, amd_vrda_fmax)
|
|
||||||
EIGEN_AOCL_VML_BINARY_CALL_DOUBLE(min, amd_vrda_fmin)
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_ASSIGN_AOCL_H
|
|
||||||
@@ -1,183 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2011, Intel Corporation. All rights reserved.
|
|
||||||
Copyright (C) 2015 Gael Guennebaud <gael.guennebaud@inria.fr>
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
* Neither the name of Intel Corporation nor the names of its contributors may
|
|
||||||
be used to endorse or promote products derived from this software without
|
|
||||||
specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
********************************************************************************
|
|
||||||
* Content : Eigen bindings to Intel(R) MKL
|
|
||||||
* MKL VML support for coefficient-wise unary Eigen expressions like a=b.sin()
|
|
||||||
********************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef EIGEN_ASSIGN_VML_H
|
|
||||||
#define EIGEN_ASSIGN_VML_H
|
|
||||||
|
|
||||||
// IWYU pragma: private
|
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template <typename Dst, typename Src>
|
|
||||||
class vml_assign_traits {
|
|
||||||
private:
|
|
||||||
enum {
|
|
||||||
DstHasDirectAccess = Dst::Flags & DirectAccessBit,
|
|
||||||
SrcHasDirectAccess = Src::Flags & DirectAccessBit,
|
|
||||||
StorageOrdersAgree = (int(Dst::IsRowMajor) == int(Src::IsRowMajor)),
|
|
||||||
InnerSize = int(Dst::IsVectorAtCompileTime) ? int(Dst::SizeAtCompileTime)
|
|
||||||
: int(Dst::Flags) & RowMajorBit ? int(Dst::ColsAtCompileTime)
|
|
||||||
: int(Dst::RowsAtCompileTime),
|
|
||||||
InnerMaxSize = int(Dst::IsVectorAtCompileTime) ? int(Dst::MaxSizeAtCompileTime)
|
|
||||||
: int(Dst::Flags) & RowMajorBit ? int(Dst::MaxColsAtCompileTime)
|
|
||||||
: int(Dst::MaxRowsAtCompileTime),
|
|
||||||
MaxSizeAtCompileTime = Dst::SizeAtCompileTime,
|
|
||||||
|
|
||||||
MightEnableVml = bool(StorageOrdersAgree) && bool(DstHasDirectAccess) && bool(SrcHasDirectAccess) &&
|
|
||||||
Src::InnerStrideAtCompileTime == 1 && Dst::InnerStrideAtCompileTime == 1,
|
|
||||||
MightLinearize = bool(MightEnableVml) && (int(Dst::Flags) & int(Src::Flags) & LinearAccessBit),
|
|
||||||
VmlSize = bool(MightLinearize) ? MaxSizeAtCompileTime : InnerMaxSize,
|
|
||||||
LargeEnough = (VmlSize == Dynamic) || VmlSize >= EIGEN_MKL_VML_THRESHOLD
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum { EnableVml = MightEnableVml && LargeEnough, Traversal = MightLinearize ? LinearTraversal : DefaultTraversal };
|
|
||||||
};
|
|
||||||
|
|
||||||
#define EIGEN_PP_EXPAND(ARG) ARG
|
|
||||||
#if !defined(EIGEN_FAST_MATH) || (EIGEN_FAST_MATH != 1)
|
|
||||||
#define EIGEN_VMLMODE_EXPAND_xLA , VML_HA
|
|
||||||
#else
|
|
||||||
#define EIGEN_VMLMODE_EXPAND_xLA , VML_LA
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define EIGEN_VMLMODE_EXPAND_x_
|
|
||||||
|
|
||||||
#define EIGEN_VMLMODE_PREFIX_xLA vm
|
|
||||||
#define EIGEN_VMLMODE_PREFIX_x_ v
|
|
||||||
#define EIGEN_VMLMODE_PREFIX(VMLMODE) EIGEN_CAT(EIGEN_VMLMODE_PREFIX_x, VMLMODE)
|
|
||||||
|
|
||||||
#define EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE, VMLMODE) \
|
|
||||||
template <typename DstXprType, typename SrcXprNested> \
|
|
||||||
struct Assignment<DstXprType, CwiseUnaryOp<scalar_##EIGENOP##_op<EIGENTYPE>, SrcXprNested>, \
|
|
||||||
assign_op<EIGENTYPE, EIGENTYPE>, Dense2Dense, \
|
|
||||||
std::enable_if_t<vml_assign_traits<DstXprType, SrcXprNested>::EnableVml>> { \
|
|
||||||
typedef CwiseUnaryOp<scalar_##EIGENOP##_op<EIGENTYPE>, SrcXprNested> SrcXprType; \
|
|
||||||
static void run(DstXprType &dst, const SrcXprType &src, const assign_op<EIGENTYPE, EIGENTYPE> &func) { \
|
|
||||||
resize_if_allowed(dst, src, func); \
|
|
||||||
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols()); \
|
|
||||||
if (vml_assign_traits<DstXprType, SrcXprNested>::Traversal == (int)LinearTraversal) { \
|
|
||||||
VMLOP(dst.size(), (const VMLTYPE *)src.nestedExpression().data(), \
|
|
||||||
(VMLTYPE *)dst.data() EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_x##VMLMODE)); \
|
|
||||||
} else { \
|
|
||||||
const Index outerSize = dst.outerSize(); \
|
|
||||||
for (Index outer = 0; outer < outerSize; ++outer) { \
|
|
||||||
const EIGENTYPE *src_ptr = src.IsRowMajor ? &(src.nestedExpression().coeffRef(outer, 0)) \
|
|
||||||
: &(src.nestedExpression().coeffRef(0, outer)); \
|
|
||||||
EIGENTYPE *dst_ptr = dst.IsRowMajor ? &(dst.coeffRef(outer, 0)) : &(dst.coeffRef(0, outer)); \
|
|
||||||
VMLOP(dst.innerSize(), (const VMLTYPE *)src_ptr, \
|
|
||||||
(VMLTYPE *)dst_ptr EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_x##VMLMODE)); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
};
|
|
||||||
|
|
||||||
#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(EIGENOP, VMLOP, VMLMODE) \
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, EIGEN_CAT(EIGEN_VMLMODE_PREFIX(VMLMODE), s##VMLOP), float, float, VMLMODE) \
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, EIGEN_CAT(EIGEN_VMLMODE_PREFIX(VMLMODE), d##VMLOP), double, double, VMLMODE)
|
|
||||||
|
|
||||||
#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_CPLX(EIGENOP, VMLOP, VMLMODE) \
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, EIGEN_CAT(EIGEN_VMLMODE_PREFIX(VMLMODE), c##VMLOP), scomplex, \
|
|
||||||
MKL_Complex8, VMLMODE) \
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, EIGEN_CAT(EIGEN_VMLMODE_PREFIX(VMLMODE), z##VMLOP), dcomplex, \
|
|
||||||
MKL_Complex16, VMLMODE)
|
|
||||||
|
|
||||||
#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS(EIGENOP, VMLOP, VMLMODE) \
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(EIGENOP, VMLOP, VMLMODE) \
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_CPLX(EIGENOP, VMLOP, VMLMODE)
|
|
||||||
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(sin, Sin, LA)
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(asin, Asin, LA)
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(sinh, Sinh, LA)
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(cos, Cos, LA)
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(acos, Acos, LA)
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(cosh, Cosh, LA)
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(tan, Tan, LA)
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(atan, Atan, LA)
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(tanh, Tanh, LA)
|
|
||||||
// EIGEN_MKL_VML_DECLARE_UNARY_CALLS(abs, Abs, _)
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(exp, Exp, LA)
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(log, Ln, LA)
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(log10, Log10, LA)
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(sqrt, Sqrt, _)
|
|
||||||
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(square, Sqr, _)
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_CPLX(arg, Arg, _)
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(round, Round, _)
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(floor, Floor, _)
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(ceil, Ceil, _)
|
|
||||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(cbrt, Cbrt, _)
|
|
||||||
|
|
||||||
#define EIGEN_MKL_VML_DECLARE_POW_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE, VMLMODE) \
|
|
||||||
template <typename DstXprType, typename SrcXprNested, typename Plain> \
|
|
||||||
struct Assignment<DstXprType, \
|
|
||||||
CwiseBinaryOp<scalar_##EIGENOP##_op<EIGENTYPE, EIGENTYPE>, SrcXprNested, \
|
|
||||||
const CwiseNullaryOp<internal::scalar_constant_op<EIGENTYPE>, Plain>>, \
|
|
||||||
assign_op<EIGENTYPE, EIGENTYPE>, Dense2Dense, \
|
|
||||||
std::enable_if_t<vml_assign_traits<DstXprType, SrcXprNested>::EnableVml>> { \
|
|
||||||
typedef CwiseBinaryOp<scalar_##EIGENOP##_op<EIGENTYPE, EIGENTYPE>, SrcXprNested, \
|
|
||||||
const CwiseNullaryOp<internal::scalar_constant_op<EIGENTYPE>, Plain>> \
|
|
||||||
SrcXprType; \
|
|
||||||
static void run(DstXprType &dst, const SrcXprType &src, const assign_op<EIGENTYPE, EIGENTYPE> &func) { \
|
|
||||||
resize_if_allowed(dst, src, func); \
|
|
||||||
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols()); \
|
|
||||||
VMLTYPE exponent = reinterpret_cast<const VMLTYPE &>(src.rhs().functor().m_other); \
|
|
||||||
if (vml_assign_traits<DstXprType, SrcXprNested>::Traversal == LinearTraversal) { \
|
|
||||||
VMLOP(dst.size(), (const VMLTYPE *)src.lhs().data(), exponent, \
|
|
||||||
(VMLTYPE *)dst.data() EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_x##VMLMODE)); \
|
|
||||||
} else { \
|
|
||||||
const Index outerSize = dst.outerSize(); \
|
|
||||||
for (Index outer = 0; outer < outerSize; ++outer) { \
|
|
||||||
const EIGENTYPE *src_ptr = \
|
|
||||||
src.IsRowMajor ? &(src.lhs().coeffRef(outer, 0)) : &(src.lhs().coeffRef(0, outer)); \
|
|
||||||
EIGENTYPE *dst_ptr = dst.IsRowMajor ? &(dst.coeffRef(outer, 0)) : &(dst.coeffRef(0, outer)); \
|
|
||||||
VMLOP(dst.innerSize(), (const VMLTYPE *)src_ptr, exponent, \
|
|
||||||
(VMLTYPE *)dst_ptr EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_x##VMLMODE)); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
};
|
|
||||||
|
|
||||||
EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmsPowx, float, float, LA)
|
|
||||||
EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmdPowx, double, double, LA)
|
|
||||||
EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmcPowx, scomplex, MKL_Complex8, LA)
|
|
||||||
EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmzPowx, dcomplex, MKL_Complex16, LA)
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_ASSIGN_VML_H
|
|
||||||
@@ -3,23 +3,36 @@
|
|||||||
//
|
//
|
||||||
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_BANDMATRIX_H
|
#ifndef EIGEN_BANDMATRIX_H
|
||||||
#define EIGEN_BANDMATRIX_H
|
#define EIGEN_BANDMATRIX_H
|
||||||
|
|
||||||
// IWYU pragma: private
|
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
class BandMatrixBase : public EigenBase<Derived> {
|
class BandMatrixBase : public EigenBase<Derived>
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
Flags = internal::traits<Derived>::Flags,
|
Flags = internal::traits<Derived>::Flags,
|
||||||
CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
|
CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
|
||||||
@@ -33,20 +46,23 @@ class BandMatrixBase : public EigenBase<Derived> {
|
|||||||
};
|
};
|
||||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||||
typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> DenseMatrixType;
|
typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> DenseMatrixType;
|
||||||
typedef typename DenseMatrixType::StorageIndex StorageIndex;
|
typedef typename DenseMatrixType::Index Index;
|
||||||
typedef typename internal::traits<Derived>::CoefficientsType CoefficientsType;
|
typedef typename internal::traits<Derived>::CoefficientsType CoefficientsType;
|
||||||
typedef EigenBase<Derived> Base;
|
typedef EigenBase<Derived> Base;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
enum {
|
enum {
|
||||||
DataRowsAtCompileTime = ((Supers != Dynamic) && (Subs != Dynamic)) ? 1 + Supers + Subs : Dynamic,
|
DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic))
|
||||||
SizeAtCompileTime = min_size_prefer_dynamic(RowsAtCompileTime, ColsAtCompileTime)
|
? 1 + Supers + Subs
|
||||||
|
: Dynamic,
|
||||||
|
SizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime,ColsAtCompileTime)
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using Base::cols;
|
|
||||||
using Base::derived;
|
using Base::derived;
|
||||||
using Base::rows;
|
using Base::rows;
|
||||||
|
using Base::cols;
|
||||||
|
|
||||||
/** \returns the number of super diagonals */
|
/** \returns the number of super diagonals */
|
||||||
inline Index supers() const { return derived().supers(); }
|
inline Index supers() const { return derived().supers(); }
|
||||||
@@ -63,90 +79,94 @@ class BandMatrixBase : public EigenBase<Derived> {
|
|||||||
/** \returns a vector expression of the \a i -th column,
|
/** \returns a vector expression of the \a i -th column,
|
||||||
* only the meaningful part is returned.
|
* only the meaningful part is returned.
|
||||||
* \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())
|
||||||
|
{
|
||||||
start = supers()-i;
|
start = supers()-i;
|
||||||
len = (std::min)(rows(),std::max<Index>(0,coeffs().rows() - (supers()-i)));
|
len = (std::min)(rows(),std::max<Index>(0,coeffs().rows() - (supers()-i)));
|
||||||
} else if (i >= rows() - subs())
|
}
|
||||||
|
else if (i>=rows()-subs())
|
||||||
len = std::max<Index>(0,coeffs().rows() - (i + 1 - rows() + subs()));
|
len = std::max<Index>(0,coeffs().rows() - (i + 1 - rows() + subs()));
|
||||||
return Block<CoefficientsType,Dynamic,1>(coeffs(), start, i, len, 1);
|
return Block<CoefficientsType,Dynamic,1>(coeffs(), start, i, len, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns a vector expression of the main diagonal */
|
/** \returns a vector expression of the main diagonal */
|
||||||
inline Block<CoefficientsType, 1, SizeAtCompileTime> diagonal() {
|
inline Block<CoefficientsType,1,SizeAtCompileTime> diagonal()
|
||||||
return Block<CoefficientsType, 1, SizeAtCompileTime>(coeffs(), supers(), 0, 1, (std::min)(rows(), cols()));
|
{ return Block<CoefficientsType,1,SizeAtCompileTime>(coeffs(),supers(),0,1,(std::min)(rows(),cols())); }
|
||||||
}
|
|
||||||
|
|
||||||
/** \returns a vector expression of the main diagonal (const version) */
|
/** \returns a vector expression of the main diagonal (const version) */
|
||||||
inline const Block<const CoefficientsType, 1, SizeAtCompileTime> diagonal() const {
|
inline const Block<const CoefficientsType,1,SizeAtCompileTime> diagonal() const
|
||||||
return Block<const CoefficientsType, 1, SizeAtCompileTime>(coeffs(), supers(), 0, 1, (std::min)(rows(), cols()));
|
{ return Block<const CoefficientsType,1,SizeAtCompileTime>(coeffs(),supers(),0,1,(std::min)(rows(),cols())); }
|
||||||
}
|
|
||||||
|
|
||||||
template <int Index>
|
template<int Index> struct DiagonalIntReturnType {
|
||||||
struct DiagonalIntReturnType {
|
|
||||||
enum {
|
enum {
|
||||||
ReturnOpposite =
|
ReturnOpposite = (Options&SelfAdjoint) && (((Index)>0 && Supers==0) || ((Index)<0 && Subs==0)),
|
||||||
(int(Options) & int(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 =
|
DiagonalSize = (RowsAtCompileTime==Dynamic || ColsAtCompileTime==Dynamic)
|
||||||
(RowsAtCompileTime == Dynamic || ColsAtCompileTime == Dynamic)
|
|
||||||
? Dynamic
|
? Dynamic
|
||||||
: (ActualIndex < 0 ? min_size_prefer_dynamic(ColsAtCompileTime, RowsAtCompileTime + ActualIndex)
|
: (ActualIndex<0
|
||||||
: min_size_prefer_dynamic(RowsAtCompileTime, ColsAtCompileTime - ActualIndex))
|
? EIGEN_SIZE_MIN_PREFER_DYNAMIC(ColsAtCompileTime, RowsAtCompileTime + ActualIndex)
|
||||||
|
: EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime, ColsAtCompileTime - ActualIndex))
|
||||||
};
|
};
|
||||||
typedef Block<CoefficientsType,1, DiagonalSize> BuildType;
|
typedef Block<CoefficientsType,1, DiagonalSize> BuildType;
|
||||||
typedef std::conditional_t<Conjugate, CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, BuildType>, BuildType>
|
typedef typename internal::conditional<Conjugate,
|
||||||
Type;
|
CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>,BuildType >,
|
||||||
|
BuildType>::type Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \returns a vector expression of the \a N -th sub or super diagonal */
|
/** \returns a vector expression of the \a N -th sub or super diagonal */
|
||||||
template <int N>
|
template<int N> inline typename DiagonalIntReturnType<N>::Type diagonal()
|
||||||
inline typename DiagonalIntReturnType<N>::Type diagonal() {
|
{
|
||||||
return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers()-N, (std::max)(0,N), 1, diagonalLength(N));
|
return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers()-N, (std::max)(0,N), 1, diagonalLength(N));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns a vector expression of the \a N -th sub or super diagonal */
|
/** \returns a vector expression of the \a N -th sub or super diagonal */
|
||||||
template <int N>
|
template<int N> inline const typename DiagonalIntReturnType<N>::Type diagonal() const
|
||||||
inline const typename DiagonalIntReturnType<N>::Type diagonal() const {
|
{
|
||||||
return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers()-N, (std::max)(0,N), 1, diagonalLength(N));
|
return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers()-N, (std::max)(0,N), 1, diagonalLength(N));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns a vector expression of the \a i -th sub or super diagonal */
|
/** \returns a vector expression of the \a i -th sub or super diagonal */
|
||||||
inline Block<CoefficientsType, 1, Dynamic> diagonal(Index i) {
|
inline Block<CoefficientsType,1,Dynamic> diagonal(Index i)
|
||||||
|
{
|
||||||
eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers()));
|
eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers()));
|
||||||
return Block<CoefficientsType,1,Dynamic>(coeffs(), supers()-i, std::max<Index>(0,i), 1, diagonalLength(i));
|
return Block<CoefficientsType,1,Dynamic>(coeffs(), supers()-i, std::max<Index>(0,i), 1, diagonalLength(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns a vector expression of the \a i -th sub or super diagonal */
|
/** \returns a vector expression of the \a i -th sub or super diagonal */
|
||||||
inline const Block<const CoefficientsType, 1, Dynamic> diagonal(Index i) const {
|
inline const Block<const CoefficientsType,1,Dynamic> diagonal(Index i) const
|
||||||
|
{
|
||||||
eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers()));
|
eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers()));
|
||||||
return Block<const CoefficientsType, 1, Dynamic>(coeffs(), supers() - i, std::max<Index>(0, i), 1,
|
return Block<const CoefficientsType,1,Dynamic>(coeffs(), supers()-i, std::max<Index>(0,i), 1, diagonalLength(i));
|
||||||
diagonalLength(i));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Dest>
|
template<typename Dest> inline void evalTo(Dest& dst) const
|
||||||
inline void evalTo(Dest& dst) const {
|
{
|
||||||
dst.resize(rows(),cols());
|
dst.resize(rows(),cols());
|
||||||
dst.setZero();
|
dst.setZero();
|
||||||
dst.diagonal() = diagonal();
|
dst.diagonal() = diagonal();
|
||||||
for (Index i = 1; i <= supers(); ++i) dst.diagonal(i) = diagonal(i);
|
for (Index i=1; i<=supers();++i)
|
||||||
for (Index i = 1; i <= subs(); ++i) dst.diagonal(-i) = diagonal(-i);
|
dst.diagonal(i) = diagonal(i);
|
||||||
|
for (Index i=1; i<=subs();++i)
|
||||||
|
dst.diagonal(-i) = diagonal(-i);
|
||||||
}
|
}
|
||||||
|
|
||||||
DenseMatrixType toDenseMatrix() const {
|
DenseMatrixType toDenseMatrix() const
|
||||||
|
{
|
||||||
DenseMatrixType res(rows(),cols());
|
DenseMatrixType res(rows(),cols());
|
||||||
evalTo(res);
|
evalTo(res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
inline Index diagonalLength(Index i) const {
|
|
||||||
return i < 0 ? (std::min)(cols(), rows() + i) : (std::min)(rows(), cols() - i);
|
inline Index diagonalLength(Index i) const
|
||||||
}
|
{ return i<0 ? (std::min)(cols(),rows()+i) : (std::min)(rows(),cols()-i); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -155,12 +175,12 @@ class BandMatrixBase : public EigenBase<Derived> {
|
|||||||
*
|
*
|
||||||
* \brief Represents a rectangular matrix with a banded storage
|
* \brief Represents a rectangular matrix with a banded storage
|
||||||
*
|
*
|
||||||
* \tparam Scalar_ Numeric type, i.e. float, double, int
|
* \param _Scalar Numeric type, i.e. float, double, int
|
||||||
* \tparam Rows_ Number of rows, or \b Dynamic
|
* \param Rows Number of rows, or \b Dynamic
|
||||||
* \tparam Cols_ Number of columns, or \b Dynamic
|
* \param Cols Number of columns, or \b Dynamic
|
||||||
* \tparam Supers_ Number of super diagonal
|
* \param Supers Number of super diagonal
|
||||||
* \tparam Subs_ Number of sub diagonal
|
* \param Subs Number of sub diagonal
|
||||||
* \tparam Options_ A combination of either \b #RowMajor or \b #ColMajor, and of \b #SelfAdjoint
|
* \param _Options A combination of either \b #RowMajor or \b #ColMajor, and of \b #SelfAdjoint
|
||||||
* The former controls \ref TopicStorageOrders "storage order", and defaults to
|
* The former controls \ref TopicStorageOrders "storage order", and defaults to
|
||||||
* column-major. The latter controls whether the matrix represents a selfadjoint
|
* column-major. The latter controls whether the matrix represents a selfadjoint
|
||||||
* matrix in which case either Supers of Subs have to be null.
|
* matrix in which case either Supers of Subs have to be null.
|
||||||
@@ -168,116 +188,126 @@ class BandMatrixBase : public EigenBase<Derived> {
|
|||||||
* \sa class TridiagonalMatrix
|
* \sa class TridiagonalMatrix
|
||||||
*/
|
*/
|
||||||
|
|
||||||
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>
|
||||||
struct traits<BandMatrix<Scalar_, Rows_, Cols_, Supers_, Subs_, Options_> > {
|
struct traits<BandMatrix<_Scalar,_Rows,_Cols,_Supers,_Subs,_Options> >
|
||||||
typedef Scalar_ Scalar;
|
{
|
||||||
|
typedef _Scalar Scalar;
|
||||||
typedef Dense StorageKind;
|
typedef Dense StorageKind;
|
||||||
typedef Eigen::Index StorageIndex;
|
typedef DenseIndex Index;
|
||||||
enum {
|
enum {
|
||||||
CoeffReadCost = NumTraits<Scalar>::ReadCost,
|
CoeffReadCost = NumTraits<Scalar>::ReadCost,
|
||||||
RowsAtCompileTime = Rows_,
|
RowsAtCompileTime = _Rows,
|
||||||
ColsAtCompileTime = Cols_,
|
ColsAtCompileTime = _Cols,
|
||||||
MaxRowsAtCompileTime = Rows_,
|
MaxRowsAtCompileTime = _Rows,
|
||||||
MaxColsAtCompileTime = Cols_,
|
MaxColsAtCompileTime = _Cols,
|
||||||
Flags = LvalueBit,
|
Flags = LvalueBit,
|
||||||
Supers = Supers_,
|
Supers = _Supers,
|
||||||
Subs = Subs_,
|
Subs = _Subs,
|
||||||
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>
|
typedef Matrix<Scalar,DataRowsAtCompileTime,ColsAtCompileTime,Options&RowMajor?RowMajor:ColMajor> CoefficientsType;
|
||||||
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>
|
||||||
class BandMatrix : public BandMatrixBase<BandMatrix<Scalar_, Rows, Cols, Supers, Subs, Options> > {
|
class BandMatrix : public BandMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs,Options> >
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef typename internal::traits<BandMatrix>::Scalar Scalar;
|
typedef typename internal::traits<BandMatrix>::Scalar Scalar;
|
||||||
typedef typename internal::traits<BandMatrix>::StorageIndex StorageIndex;
|
typedef typename internal::traits<BandMatrix>::Index Index;
|
||||||
typedef typename internal::traits<BandMatrix>::CoefficientsType CoefficientsType;
|
typedef typename internal::traits<BandMatrix>::CoefficientsType CoefficientsType;
|
||||||
|
|
||||||
explicit inline BandMatrix(Index rows = Rows, Index cols = Cols, Index supers = Supers, Index subs = Subs)
|
inline BandMatrix(Index rows=Rows, Index cols=Cols, Index supers=Supers, Index subs=Subs)
|
||||||
: m_coeffs(1 + supers + subs, cols), m_rows(rows), m_supers(supers), m_subs(subs) {}
|
: m_coeffs(1+supers+subs,cols),
|
||||||
|
m_rows(rows), m_supers(supers), m_subs(subs)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/** \returns the number of columns */
|
/** \returns the number of columns */
|
||||||
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 */
|
||||||
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 */
|
||||||
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 */
|
||||||
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; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
CoefficientsType m_coeffs;
|
CoefficientsType m_coeffs;
|
||||||
internal::variable_if_dynamic<Index, Rows> m_rows;
|
internal::variable_if_dynamic<Index, Rows> m_rows;
|
||||||
internal::variable_if_dynamic<Index, Supers> m_supers;
|
internal::variable_if_dynamic<Index, Supers> m_supers;
|
||||||
internal::variable_if_dynamic<Index, Subs> m_subs;
|
internal::variable_if_dynamic<Index, Subs> m_subs;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename CoefficientsType_, int Rows_, int Cols_, int Supers_, int Subs_, int Options_>
|
template<typename _CoefficientsType,int _Rows, int _Cols, int _Supers, int _Subs,int _Options>
|
||||||
class BandMatrixWrapper;
|
class BandMatrixWrapper;
|
||||||
|
|
||||||
template <typename CoefficientsType_, int Rows_, int Cols_, int Supers_, int Subs_, int Options_>
|
template<typename _CoefficientsType,int _Rows, int _Cols, int _Supers, int _Subs,int _Options>
|
||||||
struct traits<BandMatrixWrapper<CoefficientsType_, Rows_, Cols_, Supers_, Subs_, Options_> > {
|
struct traits<BandMatrixWrapper<_CoefficientsType,_Rows,_Cols,_Supers,_Subs,_Options> >
|
||||||
typedef typename CoefficientsType_::Scalar Scalar;
|
{
|
||||||
typedef typename CoefficientsType_::StorageKind StorageKind;
|
typedef typename _CoefficientsType::Scalar Scalar;
|
||||||
typedef typename CoefficientsType_::StorageIndex StorageIndex;
|
typedef typename _CoefficientsType::StorageKind StorageKind;
|
||||||
|
typedef typename _CoefficientsType::Index Index;
|
||||||
enum {
|
enum {
|
||||||
CoeffReadCost = internal::traits<CoefficientsType_>::CoeffReadCost,
|
CoeffReadCost = internal::traits<_CoefficientsType>::CoeffReadCost,
|
||||||
RowsAtCompileTime = Rows_,
|
RowsAtCompileTime = _Rows,
|
||||||
ColsAtCompileTime = Cols_,
|
ColsAtCompileTime = _Cols,
|
||||||
MaxRowsAtCompileTime = Rows_,
|
MaxRowsAtCompileTime = _Rows,
|
||||||
MaxColsAtCompileTime = Cols_,
|
MaxColsAtCompileTime = _Cols,
|
||||||
Flags = LvalueBit,
|
Flags = LvalueBit,
|
||||||
Supers = Supers_,
|
Supers = _Supers,
|
||||||
Subs = Subs_,
|
Subs = _Subs,
|
||||||
Options = Options_,
|
Options = _Options,
|
||||||
DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic
|
DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic
|
||||||
};
|
};
|
||||||
typedef CoefficientsType_ CoefficientsType;
|
typedef _CoefficientsType CoefficientsType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename CoefficientsType_, int Rows_, int Cols_, int Supers_, int Subs_, int Options_>
|
template<typename _CoefficientsType,int _Rows, int _Cols, int _Supers, int _Subs,int _Options>
|
||||||
class BandMatrixWrapper
|
class BandMatrixWrapper : public BandMatrixBase<BandMatrixWrapper<_CoefficientsType,_Rows,_Cols,_Supers,_Subs,_Options> >
|
||||||
: public BandMatrixBase<BandMatrixWrapper<CoefficientsType_, Rows_, Cols_, Supers_, Subs_, Options_> > {
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef typename internal::traits<BandMatrixWrapper>::Scalar Scalar;
|
typedef typename internal::traits<BandMatrixWrapper>::Scalar Scalar;
|
||||||
typedef typename internal::traits<BandMatrixWrapper>::CoefficientsType CoefficientsType;
|
typedef typename internal::traits<BandMatrixWrapper>::CoefficientsType CoefficientsType;
|
||||||
typedef typename internal::traits<BandMatrixWrapper>::StorageIndex StorageIndex;
|
typedef typename internal::traits<BandMatrixWrapper>::Index Index;
|
||||||
|
|
||||||
explicit inline BandMatrixWrapper(const CoefficientsType& coeffs, Index rows = Rows_, Index cols = Cols_,
|
inline BandMatrixWrapper(const CoefficientsType& coeffs, Index rows=_Rows, Index cols=_Cols, Index supers=_Supers, Index subs=_Subs)
|
||||||
Index supers = Supers_, Index subs = Subs_)
|
: m_coeffs(coeffs),
|
||||||
: m_coeffs(coeffs), m_rows(rows), m_supers(supers), m_subs(subs) {
|
m_rows(rows), m_supers(supers), m_subs(subs)
|
||||||
|
{
|
||||||
EIGEN_UNUSED_VARIABLE(cols);
|
EIGEN_UNUSED_VARIABLE(cols);
|
||||||
// eigen_assert(coeffs.cols()==cols() && (supers()+subs()+1)==coeffs.rows());
|
//internal::assert(coeffs.cols()==cols() && (supers()+subs()+1)==coeffs.rows());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the number of columns */
|
/** \returns the number of columns */
|
||||||
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 */
|
||||||
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 */
|
||||||
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 */
|
||||||
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; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
const CoefficientsType& m_coeffs;
|
const CoefficientsType& m_coeffs;
|
||||||
internal::variable_if_dynamic<Index, Rows_> m_rows;
|
internal::variable_if_dynamic<Index, _Rows> m_rows;
|
||||||
internal::variable_if_dynamic<Index, Supers_> m_supers;
|
internal::variable_if_dynamic<Index, _Supers> m_supers;
|
||||||
internal::variable_if_dynamic<Index, Subs_> m_subs;
|
internal::variable_if_dynamic<Index, _Subs> m_subs;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -286,53 +316,31 @@ class BandMatrixWrapper
|
|||||||
*
|
*
|
||||||
* \brief Represents a tridiagonal matrix with a compact banded storage
|
* \brief Represents a tridiagonal matrix with a compact banded storage
|
||||||
*
|
*
|
||||||
* \tparam Scalar Numeric type, i.e. float, double, int
|
* \param _Scalar Numeric type, i.e. float, double, int
|
||||||
* \tparam Size Number of rows and cols, or \b Dynamic
|
* \param Size Number of rows and cols, or \b Dynamic
|
||||||
* \tparam Options Can be 0 or \b SelfAdjoint
|
* \param _Options Can be 0 or \b SelfAdjoint
|
||||||
*
|
*
|
||||||
* \sa class BandMatrix
|
* \sa class BandMatrix
|
||||||
*/
|
*/
|
||||||
template<typename Scalar, int Size, int Options>
|
template<typename Scalar, int Size, int Options>
|
||||||
class TridiagonalMatrix : public BandMatrix<Scalar, Size, Size, Options & SelfAdjoint ? 0 : 1, 1, Options | RowMajor> {
|
class TridiagonalMatrix : public BandMatrix<Scalar,Size,Size,Options&SelfAdjoint?0:1,1,Options|RowMajor>
|
||||||
|
{
|
||||||
typedef BandMatrix<Scalar,Size,Size,Options&SelfAdjoint?0:1,1,Options|RowMajor> Base;
|
typedef BandMatrix<Scalar,Size,Size,Options&SelfAdjoint?0:1,1,Options|RowMajor> Base;
|
||||||
typedef typename Base::StorageIndex StorageIndex;
|
typedef typename Base::Index Index;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TridiagonalMatrix(Index size = Size) : Base(size, size, Options & SelfAdjoint ? 0 : 1, 1) {}
|
TridiagonalMatrix(Index size = Size) : Base(size,size,Options&SelfAdjoint?0:1,1) {}
|
||||||
|
|
||||||
inline typename Base::template DiagonalIntReturnType<1>::Type super() { return Base::template diagonal<1>(); }
|
|
||||||
inline const typename Base::template DiagonalIntReturnType<1>::Type super() const {
|
|
||||||
return Base::template diagonal<1>();
|
|
||||||
}
|
|
||||||
inline typename Base::template DiagonalIntReturnType<-1>::Type sub() { return Base::template diagonal<-1>(); }
|
|
||||||
inline const typename Base::template DiagonalIntReturnType<-1>::Type sub() const {
|
|
||||||
return Base::template diagonal<-1>();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
inline typename Base::template DiagonalIntReturnType<1>::Type super()
|
||||||
|
{ return Base::template diagonal<1>(); }
|
||||||
|
inline const typename Base::template DiagonalIntReturnType<1>::Type super() const
|
||||||
|
{ return Base::template diagonal<1>(); }
|
||||||
|
inline typename Base::template DiagonalIntReturnType<-1>::Type sub()
|
||||||
|
{ return Base::template diagonal<-1>(); }
|
||||||
|
inline const typename Base::template DiagonalIntReturnType<-1>::Type sub() const
|
||||||
|
{ return Base::template diagonal<-1>(); }
|
||||||
protected:
|
protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BandShape {};
|
|
||||||
|
|
||||||
template <typename Scalar_, int Rows_, int Cols_, int Supers_, int Subs_, int Options_>
|
|
||||||
struct evaluator_traits<BandMatrix<Scalar_, Rows_, Cols_, Supers_, Subs_, Options_> >
|
|
||||||
: public evaluator_traits_base<BandMatrix<Scalar_, Rows_, Cols_, Supers_, Subs_, Options_> > {
|
|
||||||
typedef BandShape Shape;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename CoefficientsType_, int Rows_, int Cols_, int Supers_, int Subs_, int Options_>
|
|
||||||
struct evaluator_traits<BandMatrixWrapper<CoefficientsType_, Rows_, Cols_, Supers_, Subs_, Options_> >
|
|
||||||
: public evaluator_traits_base<BandMatrixWrapper<CoefficientsType_, Rows_, Cols_, Supers_, Subs_, Options_> > {
|
|
||||||
typedef BandShape Shape;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct AssignmentKind<DenseShape, BandShape> {
|
|
||||||
typedef EigenBase2EigenBase Kind;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_BANDMATRIX_H
|
#endif // EIGEN_BANDMATRIX_H
|
||||||
|
|||||||
@@ -4,90 +4,43 @@
|
|||||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
|
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_BLOCK_H
|
#ifndef EIGEN_BLOCK_H
|
||||||
#define EIGEN_BLOCK_H
|
#define EIGEN_BLOCK_H
|
||||||
|
|
||||||
// IWYU pragma: private
|
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
template <typename XprType_, int BlockRows, int BlockCols, bool InnerPanel_>
|
|
||||||
struct traits<Block<XprType_, BlockRows, BlockCols, InnerPanel_>> : traits<XprType_> {
|
|
||||||
typedef typename traits<XprType_>::Scalar Scalar;
|
|
||||||
typedef typename traits<XprType_>::StorageKind StorageKind;
|
|
||||||
typedef typename traits<XprType_>::XprKind XprKind;
|
|
||||||
typedef typename ref_selector<XprType_>::type XprTypeNested;
|
|
||||||
typedef std::remove_reference_t<XprTypeNested> XprTypeNested_;
|
|
||||||
enum {
|
|
||||||
MatrixRows = traits<XprType_>::RowsAtCompileTime,
|
|
||||||
MatrixCols = traits<XprType_>::ColsAtCompileTime,
|
|
||||||
RowsAtCompileTime = MatrixRows == 0 ? 0 : BlockRows,
|
|
||||||
ColsAtCompileTime = MatrixCols == 0 ? 0 : BlockCols,
|
|
||||||
MaxRowsAtCompileTime = BlockRows == 0 ? 0
|
|
||||||
: RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime)
|
|
||||||
: int(traits<XprType_>::MaxRowsAtCompileTime),
|
|
||||||
MaxColsAtCompileTime = BlockCols == 0 ? 0
|
|
||||||
: ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime)
|
|
||||||
: int(traits<XprType_>::MaxColsAtCompileTime),
|
|
||||||
|
|
||||||
XprTypeIsRowMajor = (int(traits<XprType_>::Flags) & RowMajorBit) != 0,
|
|
||||||
IsRowMajor = (MaxRowsAtCompileTime == 1 && MaxColsAtCompileTime != 1) ? 1
|
|
||||||
: (MaxColsAtCompileTime == 1 && MaxRowsAtCompileTime != 1) ? 0
|
|
||||||
: XprTypeIsRowMajor,
|
|
||||||
HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor),
|
|
||||||
InnerSize = IsRowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
|
|
||||||
InnerStrideAtCompileTime = HasSameStorageOrderAsXprType ? int(inner_stride_at_compile_time<XprType_>::ret)
|
|
||||||
: int(outer_stride_at_compile_time<XprType_>::ret),
|
|
||||||
OuterStrideAtCompileTime = HasSameStorageOrderAsXprType ? int(outer_stride_at_compile_time<XprType_>::ret)
|
|
||||||
: int(inner_stride_at_compile_time<XprType_>::ret),
|
|
||||||
|
|
||||||
// FIXME, this traits is rather specialized for dense object and it needs to be cleaned further
|
|
||||||
FlagsLvalueBit = is_lvalue<XprType_>::value ? LvalueBit : 0,
|
|
||||||
FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
|
|
||||||
Flags = (traits<XprType_>::Flags & (DirectAccessBit | (InnerPanel_ ? CompressedAccessBit : 0))) | FlagsLvalueBit |
|
|
||||||
FlagsRowMajorBit,
|
|
||||||
// FIXME DirectAccessBit should not be handled by expressions
|
|
||||||
//
|
|
||||||
// Alignment is needed by MapBase's assertions
|
|
||||||
// We can sefely set it to false here. Internal alignment errors will be detected by an eigen_internal_assert in the
|
|
||||||
// respective evaluator
|
|
||||||
Alignment = 0,
|
|
||||||
InnerPanel = InnerPanel_ ? 1 : 0
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename XprType, int BlockRows = Dynamic, int BlockCols = Dynamic, bool InnerPanel = false,
|
|
||||||
bool HasDirectAccess = internal::has_direct_access<XprType>::ret>
|
|
||||||
class BlockImpl_dense;
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
|
|
||||||
template <typename XprType, int BlockRows, int BlockCols, bool InnerPanel, typename StorageKind>
|
|
||||||
class BlockImpl;
|
|
||||||
|
|
||||||
/** \class Block
|
/** \class Block
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
*
|
*
|
||||||
* \brief Expression of a fixed-size or dynamic-size block
|
* \brief Expression of a fixed-size or dynamic-size block
|
||||||
*
|
*
|
||||||
* \tparam XprType the type of the expression in which we are taking a block
|
* \param XprType the type of the expression in which we are taking a block
|
||||||
* \tparam BlockRows the number of rows of the block we are taking at compile time (optional)
|
* \param BlockRows the number of rows of the block we are taking at compile time (optional)
|
||||||
* \tparam BlockCols the number of columns of the block we are taking at compile time (optional)
|
* \param BlockCols the number of columns of the block we are taking at compile time (optional)
|
||||||
* \tparam InnerPanel is true, if the block maps to a set of rows of a row major matrix or
|
* \param _DirectAccessStatus \internal used for partial specialization
|
||||||
* to set of columns of a column major matrix (optional). The parameter allows to determine
|
|
||||||
* at compile time whether aligned access is possible on the block expression.
|
|
||||||
*
|
*
|
||||||
* This class represents an expression of either a fixed-size or dynamic-size block. It is the return
|
* This class represents an expression of either a fixed-size or dynamic-size block. It is the return
|
||||||
* type of DenseBase::block(Index,Index,Index,Index) and DenseBase::block<int,int>(Index,Index) and
|
* type of DenseBase::block(Index,Index,Index,Index) and DenseBase::block<int,int>(Index,Index) and
|
||||||
* most of the time this is the only way it is used.
|
* most of the time this is the only way it is used.
|
||||||
*
|
*
|
||||||
* However, if you want to directly manipulate block expressions,
|
* However, if you want to directly maniputate block 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.
|
||||||
*
|
*
|
||||||
@@ -105,100 +58,68 @@ class BlockImpl;
|
|||||||
*
|
*
|
||||||
* \sa DenseBase::block(Index,Index,Index,Index), DenseBase::block(Index,Index), class VectorBlock
|
* \sa DenseBase::block(Index,Index,Index,Index), DenseBase::block(Index,Index), class VectorBlock
|
||||||
*/
|
*/
|
||||||
template <typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
|
|
||||||
class Block
|
|
||||||
: public BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, typename internal::traits<XprType>::StorageKind> {
|
|
||||||
typedef BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, typename internal::traits<XprType>::StorageKind> Impl;
|
|
||||||
using BlockHelper = internal::block_xpr_helper<Block>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// typedef typename Impl::Base Base;
|
|
||||||
typedef Impl Base;
|
|
||||||
EIGEN_GENERIC_PUBLIC_INTERFACE(Block)
|
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
|
|
||||||
|
|
||||||
typedef internal::remove_all_t<XprType> NestedExpression;
|
|
||||||
|
|
||||||
/** Column or Row constructor
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Block(XprType& xpr, Index i) : Impl(xpr, i) {
|
|
||||||
eigen_assert((i >= 0) && (((BlockRows == 1) && (BlockCols == XprType::ColsAtCompileTime) && i < xpr.rows()) ||
|
|
||||||
((BlockRows == XprType::RowsAtCompileTime) && (BlockCols == 1) && i < xpr.cols())));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Fixed-size constructor
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Block(XprType& xpr, Index startRow, Index startCol)
|
|
||||||
: Impl(xpr, startRow, startCol) {
|
|
||||||
EIGEN_STATIC_ASSERT(RowsAtCompileTime != Dynamic && ColsAtCompileTime != Dynamic,
|
|
||||||
THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
|
|
||||||
eigen_assert(startRow >= 0 && BlockRows >= 0 && startRow + BlockRows <= xpr.rows() && startCol >= 0 &&
|
|
||||||
BlockCols >= 0 && startCol + BlockCols <= xpr.cols());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Dynamic-size constructor
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Block(XprType& xpr, Index startRow, Index startCol, Index blockRows,
|
|
||||||
Index blockCols)
|
|
||||||
: Impl(xpr, startRow, startCol, blockRows, blockCols) {
|
|
||||||
eigen_assert((RowsAtCompileTime == Dynamic || RowsAtCompileTime == blockRows) &&
|
|
||||||
(ColsAtCompileTime == Dynamic || ColsAtCompileTime == blockCols));
|
|
||||||
eigen_assert(startRow >= 0 && blockRows >= 0 && startRow <= xpr.rows() - blockRows && startCol >= 0 &&
|
|
||||||
blockCols >= 0 && startCol <= xpr.cols() - blockCols);
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert nested blocks (e.g. Block<Block<MatrixType>>) to a simple block expression (Block<MatrixType>)
|
|
||||||
|
|
||||||
using ConstUnwindReturnType = Block<const typename BlockHelper::BaseType, BlockRows, BlockCols, InnerPanel>;
|
|
||||||
using UnwindReturnType = Block<typename BlockHelper::BaseType, BlockRows, BlockCols, InnerPanel>;
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ConstUnwindReturnType unwind() const {
|
|
||||||
return ConstUnwindReturnType(BlockHelper::base(*this), BlockHelper::row(*this, 0), BlockHelper::col(*this, 0),
|
|
||||||
this->rows(), this->cols());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T = Block, typename EnableIf = std::enable_if_t<!std::is_const<T>::value>>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE UnwindReturnType unwind() {
|
|
||||||
return UnwindReturnType(BlockHelper::base(*this), BlockHelper::row(*this, 0), BlockHelper::col(*this, 0),
|
|
||||||
this->rows(), this->cols());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// The generic default implementation for dense block simply forward to the internal::BlockImpl_dense
|
|
||||||
// that must be specialized for direct and non-direct access...
|
|
||||||
template <typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
|
|
||||||
class BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, Dense>
|
|
||||||
: public internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel> {
|
|
||||||
typedef internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel> Impl;
|
|
||||||
typedef typename XprType::StorageIndex StorageIndex;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef Impl Base;
|
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl)
|
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE BlockImpl(XprType& xpr, Index i) : Impl(xpr, i) {}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE BlockImpl(XprType& xpr, Index startRow, Index startCol)
|
|
||||||
: Impl(xpr, startRow, startCol) {}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE BlockImpl(XprType& xpr, Index startRow, Index startCol,
|
|
||||||
Index blockRows, Index blockCols)
|
|
||||||
: Impl(xpr, startRow, startCol, blockRows, blockCols) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
/** \internal Internal implementation of dense Blocks in the general case. */
|
|
||||||
template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool HasDirectAccess>
|
template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool HasDirectAccess>
|
||||||
class BlockImpl_dense : public internal::dense_xpr_base<Block<XprType, BlockRows, BlockCols, InnerPanel>>::type {
|
struct traits<Block<XprType, BlockRows, BlockCols, InnerPanel, HasDirectAccess> > : traits<XprType>
|
||||||
typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType;
|
{
|
||||||
typedef typename internal::ref_selector<XprType>::non_const_type XprTypeNested;
|
typedef typename traits<XprType>::Scalar Scalar;
|
||||||
|
typedef typename traits<XprType>::StorageKind StorageKind;
|
||||||
|
typedef typename traits<XprType>::XprKind XprKind;
|
||||||
|
typedef typename nested<XprType>::type XprTypeNested;
|
||||||
|
typedef typename remove_reference<XprTypeNested>::type _XprTypeNested;
|
||||||
|
enum{
|
||||||
|
MatrixRows = traits<XprType>::RowsAtCompileTime,
|
||||||
|
MatrixCols = traits<XprType>::ColsAtCompileTime,
|
||||||
|
RowsAtCompileTime = MatrixRows == 0 ? 0 : BlockRows,
|
||||||
|
ColsAtCompileTime = MatrixCols == 0 ? 0 : BlockCols,
|
||||||
|
MaxRowsAtCompileTime = BlockRows==0 ? 0
|
||||||
|
: RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime)
|
||||||
|
: int(traits<XprType>::MaxRowsAtCompileTime),
|
||||||
|
MaxColsAtCompileTime = BlockCols==0 ? 0
|
||||||
|
: ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime)
|
||||||
|
: int(traits<XprType>::MaxColsAtCompileTime),
|
||||||
|
XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0,
|
||||||
|
IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1
|
||||||
|
: (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
|
||||||
|
: XprTypeIsRowMajor,
|
||||||
|
HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor),
|
||||||
|
InnerSize = IsRowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
|
||||||
|
InnerStrideAtCompileTime = HasSameStorageOrderAsXprType
|
||||||
|
? int(inner_stride_at_compile_time<XprType>::ret)
|
||||||
|
: int(outer_stride_at_compile_time<XprType>::ret),
|
||||||
|
OuterStrideAtCompileTime = HasSameStorageOrderAsXprType
|
||||||
|
? int(outer_stride_at_compile_time<XprType>::ret)
|
||||||
|
: int(inner_stride_at_compile_time<XprType>::ret),
|
||||||
|
MaskPacketAccessBit = (InnerSize == Dynamic || (InnerSize % packet_traits<Scalar>::size) == 0)
|
||||||
|
&& (InnerStrideAtCompileTime == 1)
|
||||||
|
? PacketAccessBit : 0,
|
||||||
|
MaskAlignedBit = (InnerPanel && (OuterStrideAtCompileTime!=Dynamic) && (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % 16) == 0)) ? AlignedBit : 0,
|
||||||
|
FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0,
|
||||||
|
FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
|
||||||
|
FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
|
||||||
|
Flags0 = traits<XprType>::Flags & ( (HereditaryBits & ~RowMajorBit) |
|
||||||
|
DirectAccessBit |
|
||||||
|
MaskPacketAccessBit |
|
||||||
|
MaskAlignedBit),
|
||||||
|
Flags = Flags0 | FlagsLinearAccessBit | FlagsLvalueBit | FlagsRowMajorBit
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool HasDirectAccess> class Block
|
||||||
|
: public internal::dense_xpr_base<Block<XprType, BlockRows, BlockCols, InnerPanel, HasDirectAccess> >::type
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename internal::dense_xpr_base<BlockType>::type Base;
|
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE(BlockType)
|
typedef typename internal::dense_xpr_base<Block>::type Base;
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense)
|
EIGEN_DENSE_PUBLIC_INTERFACE(Block)
|
||||||
|
|
||||||
|
class InnerIterator;
|
||||||
|
|
||||||
/** Column or Row constructor
|
/** Column or Row constructor
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC constexpr BlockImpl_dense(XprType& xpr, Index i)
|
inline Block(XprType& xpr, Index i)
|
||||||
: m_xpr(xpr),
|
: m_xpr(xpr),
|
||||||
// It is a row if and only if BlockRows==1 and BlockCols==XprType::ColsAtCompileTime,
|
// It is a row if and only if BlockRows==1 and BlockCols==XprType::ColsAtCompileTime,
|
||||||
// and it is a column if and only if BlockRows==XprType::RowsAtCompileTime and BlockCols==1,
|
// and it is a column if and only if BlockRows==XprType::RowsAtCompileTime and BlockCols==1,
|
||||||
@@ -207,190 +128,196 @@ class BlockImpl_dense : public internal::dense_xpr_base<Block<XprType, BlockRows
|
|||||||
m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0),
|
m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0),
|
||||||
m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
|
m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
|
||||||
m_blockRows(BlockRows==1 ? 1 : xpr.rows()),
|
m_blockRows(BlockRows==1 ? 1 : xpr.rows()),
|
||||||
m_blockCols(BlockCols == 1 ? 1 : xpr.cols()) {}
|
m_blockCols(BlockCols==1 ? 1 : xpr.cols())
|
||||||
|
{
|
||||||
|
eigen_assert( (i>=0) && (
|
||||||
|
((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i<xpr.rows())
|
||||||
|
||((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && i<xpr.cols())));
|
||||||
|
}
|
||||||
|
|
||||||
/** Fixed-size constructor
|
/** Fixed-size constructor
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC constexpr BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
|
inline Block(XprType& xpr, Index startRow, Index startCol)
|
||||||
: m_xpr(xpr), m_startRow(startRow), m_startCol(startCol), m_blockRows(BlockRows), m_blockCols(BlockCols) {}
|
: m_xpr(xpr), m_startRow(startRow), m_startCol(startCol),
|
||||||
|
m_blockRows(BlockRows), m_blockCols(BlockCols)
|
||||||
|
{
|
||||||
|
EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
|
||||||
|
eigen_assert(startRow >= 0 && BlockRows >= 1 && startRow + BlockRows <= xpr.rows()
|
||||||
|
&& startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= xpr.cols());
|
||||||
|
}
|
||||||
|
|
||||||
/** Dynamic-size constructor
|
/** Dynamic-size constructor
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC constexpr BlockImpl_dense(XprType& xpr, Index startRow, Index startCol, Index blockRows,
|
inline Block(XprType& xpr,
|
||||||
Index blockCols)
|
Index startRow, Index startCol,
|
||||||
: m_xpr(xpr), m_startRow(startRow), m_startCol(startCol), m_blockRows(blockRows), m_blockCols(blockCols) {}
|
Index blockRows, Index blockCols)
|
||||||
|
: m_xpr(xpr), m_startRow(startRow), m_startCol(startCol),
|
||||||
|
m_blockRows(blockRows), m_blockCols(blockCols)
|
||||||
|
{
|
||||||
|
eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
|
||||||
|
&& (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
|
||||||
|
eigen_assert(startRow >= 0 && blockRows >= 0 && startRow + blockRows <= xpr.rows()
|
||||||
|
&& startCol >= 0 && blockCols >= 0 && startCol + blockCols <= xpr.cols());
|
||||||
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index rows() const { return m_blockRows.value(); }
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
|
||||||
EIGEN_DEVICE_FUNC constexpr Index cols() const { return m_blockCols.value(); }
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index rowId, Index colId) {
|
inline Index rows() const { return m_blockRows.value(); }
|
||||||
|
inline Index cols() const { return m_blockCols.value(); }
|
||||||
|
|
||||||
|
inline Scalar& coeffRef(Index row, Index col)
|
||||||
|
{
|
||||||
EIGEN_STATIC_ASSERT_LVALUE(XprType)
|
EIGEN_STATIC_ASSERT_LVALUE(XprType)
|
||||||
return m_xpr.coeffRef(rowId + m_startRow.value(), colId + m_startCol.value());
|
return m_xpr.const_cast_derived()
|
||||||
|
.coeffRef(row + m_startRow.value(), col + m_startCol.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline const Scalar& coeffRef(Index rowId, Index colId) const {
|
inline const Scalar& coeffRef(Index row, Index col) const
|
||||||
return m_xpr.derived().coeffRef(rowId + m_startRow.value(), colId + m_startCol.value());
|
{
|
||||||
|
return m_xpr.derived()
|
||||||
|
.coeffRef(row + m_startRow.value(), col + m_startCol.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index rowId, Index colId) const {
|
EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index row, Index col) const
|
||||||
return m_xpr.coeff(rowId + m_startRow.value(), colId + m_startCol.value());
|
{
|
||||||
|
return m_xpr.coeff(row + m_startRow.value(), col + m_startCol.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index index) {
|
inline Scalar& coeffRef(Index index)
|
||||||
|
{
|
||||||
EIGEN_STATIC_ASSERT_LVALUE(XprType)
|
EIGEN_STATIC_ASSERT_LVALUE(XprType)
|
||||||
return m_xpr.coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
|
return m_xpr.const_cast_derived()
|
||||||
|
.coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
|
||||||
m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
|
m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline const Scalar& coeffRef(Index index) const {
|
inline const Scalar& coeffRef(Index index) const
|
||||||
return m_xpr.coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
|
{
|
||||||
|
return m_xpr.const_cast_derived()
|
||||||
|
.coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
|
||||||
m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
|
m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline const CoeffReturnType coeff(Index index) const {
|
inline const CoeffReturnType coeff(Index index) const
|
||||||
return m_xpr.coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
|
{
|
||||||
|
return m_xpr
|
||||||
|
.coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
|
||||||
m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
|
m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode>
|
template<int LoadMode>
|
||||||
EIGEN_DEVICE_FUNC inline PacketScalar packet(Index rowId, Index colId) const {
|
inline PacketScalar packet(Index row, Index col) const
|
||||||
return m_xpr.template packet<Unaligned>(rowId + m_startRow.value(), colId + m_startCol.value());
|
{
|
||||||
|
return m_xpr.template packet<Unaligned>
|
||||||
|
(row + m_startRow.value(), col + 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 row, Index col, const PacketScalar& x)
|
||||||
m_xpr.template writePacket<Unaligned>(rowId + m_startRow.value(), colId + m_startCol.value(), val);
|
{
|
||||||
|
m_xpr.const_cast_derived().template writePacket<Unaligned>
|
||||||
|
(row + m_startRow.value(), col + m_startCol.value(), x);
|
||||||
}
|
}
|
||||||
|
|
||||||
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>(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
|
{
|
||||||
|
return m_xpr.template packet<Unaligned>
|
||||||
|
(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
|
||||||
m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
|
m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode>
|
template<int LoadMode>
|
||||||
EIGEN_DEVICE_FUNC inline void writePacket(Index index, const PacketScalar& val) {
|
inline void writePacket(Index index, const PacketScalar& x)
|
||||||
m_xpr.template writePacket<Unaligned>(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
|
{
|
||||||
m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0), val);
|
m_xpr.const_cast_derived().template writePacket<Unaligned>
|
||||||
|
(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
|
||||||
|
m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0), x);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
||||||
/** \sa MapBase::data() */
|
/** \sa MapBase::data() */
|
||||||
EIGEN_DEVICE_FUNC constexpr const Scalar* data() const;
|
inline const Scalar* data() const;
|
||||||
EIGEN_DEVICE_FUNC inline Index innerStride() const;
|
inline Index innerStride() const;
|
||||||
EIGEN_DEVICE_FUNC inline Index outerStride() const;
|
inline Index outerStride() const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const internal::remove_all_t<XprTypeNested>& nestedExpression() const {
|
|
||||||
return m_xpr;
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE XprType& nestedExpression() { return m_xpr; }
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr StorageIndex startRow() const noexcept { return m_startRow.value(); }
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr StorageIndex startCol() const noexcept { return m_startCol.value(); }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
XprTypeNested m_xpr;
|
|
||||||
const internal::variable_if_dynamic<StorageIndex, (XprType::RowsAtCompileTime == 1 && BlockRows == 1) ? 0 : Dynamic>
|
const typename XprType::Nested m_xpr;
|
||||||
m_startRow;
|
const internal::variable_if_dynamic<Index, XprType::RowsAtCompileTime == 1 ? 0 : Dynamic> m_startRow;
|
||||||
const internal::variable_if_dynamic<StorageIndex, (XprType::ColsAtCompileTime == 1 && BlockCols == 1) ? 0 : Dynamic>
|
const internal::variable_if_dynamic<Index, XprType::ColsAtCompileTime == 1 ? 0 : Dynamic> m_startCol;
|
||||||
m_startCol;
|
const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_blockRows;
|
||||||
const internal::variable_if_dynamic<StorageIndex, RowsAtCompileTime> m_blockRows;
|
const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_blockCols;
|
||||||
const internal::variable_if_dynamic<StorageIndex, ColsAtCompileTime> m_blockCols;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \internal Internal implementation of dense Blocks in the direct access case.*/
|
/** \internal */
|
||||||
template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
|
template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
|
||||||
class BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel, true>
|
class Block<XprType,BlockRows,BlockCols, InnerPanel,true>
|
||||||
: public MapBase<Block<XprType, BlockRows, BlockCols, InnerPanel>> {
|
: public MapBase<Block<XprType, BlockRows, BlockCols, InnerPanel, true> >
|
||||||
typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType;
|
{
|
||||||
typedef typename internal::ref_selector<XprType>::non_const_type XprTypeNested;
|
|
||||||
enum { 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 constexpr EIGEN_ALWAYS_INLINE static Scalar* add_to_nullable_pointer(Scalar* base, Index offset) {
|
|
||||||
return base != nullptr ? base + offset : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef MapBase<BlockType> Base;
|
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE(BlockType)
|
typedef MapBase<Block> Base;
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense)
|
EIGEN_DENSE_PUBLIC_INTERFACE(Block)
|
||||||
|
|
||||||
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
|
||||||
|
|
||||||
/** Column or Row constructor
|
/** Column or Row constructor
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl_dense(XprType& xpr, Index i)
|
inline Block(XprType& xpr, Index i)
|
||||||
: Base((BlockRows == 0 || BlockCols == 0)
|
: Base(internal::const_cast_ptr(&xpr.coeffRef(
|
||||||
? nullptr
|
(BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0,
|
||||||
: add_to_nullable_pointer(
|
(BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0)),
|
||||||
xpr.data(),
|
BlockRows==1 ? 1 : xpr.rows(),
|
||||||
i * (((BlockRows == 1) && (BlockCols == XprType::ColsAtCompileTime) && (!XprTypeIsRowMajor)) ||
|
BlockCols==1 ? 1 : xpr.cols()),
|
||||||
((BlockRows == XprType::RowsAtCompileTime) && (BlockCols == 1) &&
|
m_xpr(xpr)
|
||||||
(XprTypeIsRowMajor))
|
{
|
||||||
? xpr.innerStride()
|
eigen_assert( (i>=0) && (
|
||||||
: xpr.outerStride())),
|
((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i<xpr.rows())
|
||||||
BlockRows == 1 ? 1 : xpr.rows(), BlockCols == 1 ? 1 : xpr.cols()),
|
||((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && i<xpr.cols())));
|
||||||
m_xpr(xpr),
|
|
||||||
m_startRow((BlockRows == 1) && (BlockCols == XprType::ColsAtCompileTime) ? i : 0),
|
|
||||||
m_startCol((BlockRows == XprType::RowsAtCompileTime) && (BlockCols == 1) ? i : 0) {
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Fixed-size constructor
|
/** Fixed-size constructor
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
|
inline Block(XprType& xpr, Index startRow, Index startCol)
|
||||||
: Base((BlockRows == 0 || BlockCols == 0)
|
: Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol))), m_xpr(xpr)
|
||||||
? nullptr
|
{
|
||||||
: add_to_nullable_pointer(xpr.data(),
|
eigen_assert(startRow >= 0 && BlockRows >= 1 && startRow + BlockRows <= xpr.rows()
|
||||||
xpr.innerStride() * (XprTypeIsRowMajor ? startCol : startRow) +
|
&& startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= xpr.cols());
|
||||||
xpr.outerStride() * (XprTypeIsRowMajor ? startRow : startCol))),
|
|
||||||
m_xpr(xpr),
|
|
||||||
m_startRow(startRow),
|
|
||||||
m_startCol(startCol) {
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Dynamic-size constructor
|
/** Dynamic-size constructor
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl_dense(XprType& xpr, Index startRow, Index startCol, Index blockRows,
|
inline Block(XprType& xpr,
|
||||||
Index blockCols)
|
Index startRow, Index startCol,
|
||||||
: Base((blockRows == 0 || blockCols == 0)
|
Index blockRows, Index blockCols)
|
||||||
? nullptr
|
: Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol)), blockRows, blockCols),
|
||||||
: add_to_nullable_pointer(xpr.data(),
|
m_xpr(xpr)
|
||||||
xpr.innerStride() * (XprTypeIsRowMajor ? startCol : startRow) +
|
{
|
||||||
xpr.outerStride() * (XprTypeIsRowMajor ? startRow : startCol)),
|
eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
|
||||||
blockRows, blockCols),
|
&& (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
|
||||||
m_xpr(xpr),
|
eigen_assert(startRow >= 0 && blockRows >= 0 && startRow + blockRows <= xpr.rows()
|
||||||
m_startRow(startRow),
|
&& startCol >= 0 && blockCols >= 0 && startCol + blockCols <= xpr.cols());
|
||||||
m_startCol(startCol) {
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const internal::remove_all_t<XprTypeNested>& nestedExpression() const noexcept {
|
|
||||||
return m_xpr;
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE XprType& nestedExpression() { return m_xpr; }
|
|
||||||
|
|
||||||
/** \sa MapBase::innerStride() */
|
/** \sa MapBase::innerStride() */
|
||||||
EIGEN_DEVICE_FUNC constexpr Index innerStride() const noexcept {
|
inline Index innerStride() const
|
||||||
return internal::traits<BlockType>::HasSameStorageOrderAsXprType ? m_xpr.innerStride() : m_xpr.outerStride();
|
{
|
||||||
|
return internal::traits<Block>::HasSameStorageOrderAsXprType
|
||||||
|
? m_xpr.innerStride()
|
||||||
|
: m_xpr.outerStride();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \sa MapBase::outerStride() */
|
/** \sa MapBase::outerStride() */
|
||||||
EIGEN_DEVICE_FUNC constexpr Index outerStride() const noexcept {
|
inline Index outerStride() const
|
||||||
return internal::traits<BlockType>::HasSameStorageOrderAsXprType ? m_xpr.outerStride() : m_xpr.innerStride();
|
{
|
||||||
|
return m_outerStride;
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr StorageIndex startRow() const noexcept { return m_startRow.value(); }
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr StorageIndex startCol() const noexcept { 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...
|
||||||
// META-FIXME there is no 'friend' keyword around here. Is this obsolete?
|
// META-FIXME there is no 'friend' keyword around here. Is this obsolete?
|
||||||
@@ -399,29 +326,24 @@ 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 BlockImpl_dense(XprType& xpr, const Scalar* data, Index blockRows,
|
inline Block(XprType& xpr, const Scalar* data, Index blockRows, Index blockCols)
|
||||||
Index blockCols)
|
: Base(data, blockRows, blockCols), m_xpr(xpr)
|
||||||
: Base(data, blockRows, blockCols), m_xpr(xpr) {
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void init() {
|
void init()
|
||||||
m_outerStride =
|
{
|
||||||
internal::traits<BlockType>::HasSameStorageOrderAsXprType ? m_xpr.outerStride() : m_xpr.innerStride();
|
m_outerStride = internal::traits<Block>::HasSameStorageOrderAsXprType
|
||||||
|
? m_xpr.outerStride()
|
||||||
|
: m_xpr.innerStride();
|
||||||
}
|
}
|
||||||
|
|
||||||
XprTypeNested m_xpr;
|
const typename XprType::Nested m_xpr;
|
||||||
const internal::variable_if_dynamic<StorageIndex, (XprType::RowsAtCompileTime == 1 && BlockRows == 1) ? 0 : Dynamic>
|
|
||||||
m_startRow;
|
|
||||||
const internal::variable_if_dynamic<StorageIndex, (XprType::ColsAtCompileTime == 1 && BlockCols == 1) ? 0 : Dynamic>
|
|
||||||
m_startCol;
|
|
||||||
Index m_outerStride;
|
Index m_outerStride;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_BLOCK_H
|
#endif // EIGEN_BLOCK_H
|
||||||
|
|||||||
149
Eigen/src/Core/BooleanRedux.h
Normal file
149
Eigen/src/Core/BooleanRedux.h
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
|
// for linear algebra.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
|
//
|
||||||
|
// Eigen is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef EIGEN_ALLANDANY_H
|
||||||
|
#define EIGEN_ALLANDANY_H
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template<typename Derived, int UnrollCount>
|
||||||
|
struct all_unroller
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
col = (UnrollCount-1) / Derived::RowsAtCompileTime,
|
||||||
|
row = (UnrollCount-1) % Derived::RowsAtCompileTime
|
||||||
|
};
|
||||||
|
|
||||||
|
inline static bool run(const Derived &mat)
|
||||||
|
{
|
||||||
|
return all_unroller<Derived, UnrollCount-1>::run(mat) && mat.coeff(row, col);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
struct all_unroller<Derived, 1>
|
||||||
|
{
|
||||||
|
inline static bool run(const Derived &mat) { return mat.coeff(0, 0); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
struct all_unroller<Derived, Dynamic>
|
||||||
|
{
|
||||||
|
inline static bool run(const Derived &) { return false; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived, int UnrollCount>
|
||||||
|
struct any_unroller
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
col = (UnrollCount-1) / Derived::RowsAtCompileTime,
|
||||||
|
row = (UnrollCount-1) % Derived::RowsAtCompileTime
|
||||||
|
};
|
||||||
|
|
||||||
|
inline static bool run(const Derived &mat)
|
||||||
|
{
|
||||||
|
return any_unroller<Derived, UnrollCount-1>::run(mat) || mat.coeff(row, col);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
struct any_unroller<Derived, 1>
|
||||||
|
{
|
||||||
|
inline static bool run(const Derived &mat) { return mat.coeff(0, 0); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
struct any_unroller<Derived, Dynamic>
|
||||||
|
{
|
||||||
|
inline static bool run(const Derived &) { return false; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace internal
|
||||||
|
|
||||||
|
/** \returns true if all coefficients are true
|
||||||
|
*
|
||||||
|
* Example: \include MatrixBase_all.cpp
|
||||||
|
* Output: \verbinclude MatrixBase_all.out
|
||||||
|
*
|
||||||
|
* \sa any(), Cwise::operator<()
|
||||||
|
*/
|
||||||
|
template<typename Derived>
|
||||||
|
inline bool DenseBase<Derived>::all() const
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
unroll = SizeAtCompileTime != Dynamic
|
||||||
|
&& CoeffReadCost != Dynamic
|
||||||
|
&& NumTraits<Scalar>::AddCost != Dynamic
|
||||||
|
&& SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
|
||||||
|
};
|
||||||
|
if(unroll)
|
||||||
|
return internal::all_unroller<Derived,
|
||||||
|
unroll ? int(SizeAtCompileTime) : Dynamic
|
||||||
|
>::run(derived());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(Index j = 0; j < cols(); ++j)
|
||||||
|
for(Index i = 0; i < rows(); ++i)
|
||||||
|
if (!coeff(i, j)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \returns true if at least one coefficient is true
|
||||||
|
*
|
||||||
|
* \sa all()
|
||||||
|
*/
|
||||||
|
template<typename Derived>
|
||||||
|
inline bool DenseBase<Derived>::any() const
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
unroll = SizeAtCompileTime != Dynamic
|
||||||
|
&& CoeffReadCost != Dynamic
|
||||||
|
&& NumTraits<Scalar>::AddCost != Dynamic
|
||||||
|
&& SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
|
||||||
|
};
|
||||||
|
if(unroll)
|
||||||
|
return internal::any_unroller<Derived,
|
||||||
|
unroll ? int(SizeAtCompileTime) : Dynamic
|
||||||
|
>::run(derived());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(Index j = 0; j < cols(); ++j)
|
||||||
|
for(Index i = 0; i < rows(); ++i)
|
||||||
|
if (coeff(i, j)) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \returns the number of coefficients which evaluate to true
|
||||||
|
*
|
||||||
|
* \sa all(), any()
|
||||||
|
*/
|
||||||
|
template<typename Derived>
|
||||||
|
inline typename DenseBase<Derived>::Index DenseBase<Derived>::count() const
|
||||||
|
{
|
||||||
|
return derived().template cast<bool>().template cast<Index>().sum();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // EIGEN_ALLANDANY_H
|
||||||
10
Eigen/src/Core/CMakeLists.txt
Normal file
10
Eigen/src/Core/CMakeLists.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
FILE(GLOB Eigen_Core_SRCS "*.h")
|
||||||
|
|
||||||
|
INSTALL(FILES
|
||||||
|
${Eigen_Core_SRCS}
|
||||||
|
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Core COMPONENT Devel
|
||||||
|
)
|
||||||
|
|
||||||
|
ADD_SUBDIRECTORY(products)
|
||||||
|
ADD_SUBDIRECTORY(util)
|
||||||
|
ADD_SUBDIRECTORY(arch)
|
||||||
@@ -4,18 +4,28 @@
|
|||||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
// Copyright (C) 2008 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
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_COMMAINITIALIZER_H
|
#ifndef EIGEN_COMMAINITIALIZER_H
|
||||||
#define EIGEN_COMMAINITIALIZER_H
|
#define EIGEN_COMMAINITIALIZER_H
|
||||||
|
|
||||||
// IWYU pragma: private
|
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
/** \class CommaInitializer
|
/** \class CommaInitializer
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
*
|
*
|
||||||
@@ -25,46 +35,40 @@ namespace Eigen {
|
|||||||
* the return type of MatrixBase::operator<<, and most of the time this is the only
|
* the return type of MatrixBase::operator<<, and most of the time this is the only
|
||||||
* way it is used.
|
* way it is used.
|
||||||
*
|
*
|
||||||
* \sa \blank \ref MatrixBaseCommaInitRef "MatrixBase::operator<<", CommaInitializer::finished()
|
* \sa \ref MatrixBaseCommaInitRef "MatrixBase::operator<<", CommaInitializer::finished()
|
||||||
*/
|
*/
|
||||||
template<typename XprType>
|
template<typename XprType>
|
||||||
struct CommaInitializer {
|
struct CommaInitializer
|
||||||
|
{
|
||||||
typedef typename XprType::Scalar Scalar;
|
typedef typename XprType::Scalar Scalar;
|
||||||
|
typedef typename XprType::Index Index;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC 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.template block<OtherDerived::RowsAtCompileTime, OtherDerived::ColsAtCompileTime>(0, 0, other.rows(),
|
|
||||||
other.cols()) = other;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy/Move constructor which transfers ownership. This is crucial in
|
|
||||||
* absence of return value optimization to avoid assertions during destruction. */
|
|
||||||
EIGEN_DEVICE_FUNC inline CommaInitializer(const CommaInitializer& o)
|
|
||||||
: m_xpr(o.m_xpr), m_row(o.m_row), m_col(o.m_col), m_currentBlockRows(o.m_currentBlockRows) {
|
|
||||||
// Mark original object as finished. In absence of R-value references we need to const_cast:
|
|
||||||
const_cast<CommaInitializer&>(o).m_row = m_xpr.rows();
|
|
||||||
const_cast<CommaInitializer&>(o).m_col = m_xpr.cols();
|
|
||||||
const_cast<CommaInitializer&>(o).m_currentBlockRows = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* inserts a scalar value in the target matrix */
|
/* inserts a scalar value in the target matrix */
|
||||||
EIGEN_DEVICE_FUNC CommaInitializer &operator,(const Scalar& s) {
|
CommaInitializer& operator,(const Scalar& s)
|
||||||
if (m_col == m_xpr.cols()) {
|
{
|
||||||
|
if (m_col==m_xpr.cols())
|
||||||
|
{
|
||||||
m_row+=m_currentBlockRows;
|
m_row+=m_currentBlockRows;
|
||||||
m_col = 0;
|
m_col = 0;
|
||||||
m_currentBlockRows = 1;
|
m_currentBlockRows = 1;
|
||||||
eigen_assert(m_row < m_xpr.rows() && "Too many rows passed to comma initializer (operator<<)");
|
eigen_assert(m_row<m_xpr.rows()
|
||||||
|
&& "Too many rows passed to comma initializer (operator<<)");
|
||||||
}
|
}
|
||||||
eigen_assert(m_col < m_xpr.cols() && "Too many coefficients passed to comma initializer (operator<<)");
|
eigen_assert(m_col<m_xpr.cols()
|
||||||
|
&& "Too many coefficients passed to comma initializer (operator<<)");
|
||||||
eigen_assert(m_currentBlockRows==1);
|
eigen_assert(m_currentBlockRows==1);
|
||||||
m_xpr.coeffRef(m_row, m_col++) = s;
|
m_xpr.coeffRef(m_row, m_col++) = s;
|
||||||
return *this;
|
return *this;
|
||||||
@@ -72,29 +76,34 @@ struct CommaInitializer {
|
|||||||
|
|
||||||
/* inserts a matrix expression in the target matrix */
|
/* inserts a matrix expression in the target matrix */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC CommaInitializer &operator,(const DenseBase<OtherDerived>& other) {
|
CommaInitializer& operator,(const DenseBase<OtherDerived>& other)
|
||||||
if (m_col == m_xpr.cols() && (other.cols() != 0 || other.rows() != m_currentBlockRows)) {
|
{
|
||||||
|
if (m_col==m_xpr.cols())
|
||||||
|
{
|
||||||
m_row+=m_currentBlockRows;
|
m_row+=m_currentBlockRows;
|
||||||
m_col = 0;
|
m_col = 0;
|
||||||
m_currentBlockRows = other.rows();
|
m_currentBlockRows = other.rows();
|
||||||
eigen_assert(m_row + m_currentBlockRows <= m_xpr.rows() &&
|
eigen_assert(m_row+m_currentBlockRows<=m_xpr.rows()
|
||||||
"Too many rows passed to comma initializer (operator<<)");
|
&& "Too many rows passed to comma initializer (operator<<)");
|
||||||
}
|
}
|
||||||
eigen_assert((m_col + other.cols() <= m_xpr.cols()) &&
|
eigen_assert(m_col<m_xpr.cols()
|
||||||
"Too many coefficients passed to comma initializer (operator<<)");
|
&& "Too many coefficients passed to comma initializer (operator<<)");
|
||||||
eigen_assert(m_currentBlockRows==other.rows());
|
eigen_assert(m_currentBlockRows==other.rows());
|
||||||
m_xpr.template block<OtherDerived::RowsAtCompileTime, OtherDerived::ColsAtCompileTime>(m_row, m_col, other.rows(),
|
if (OtherDerived::SizeAtCompileTime != Dynamic)
|
||||||
other.cols()) = other;
|
m_xpr.template block<OtherDerived::RowsAtCompileTime != Dynamic ? OtherDerived::RowsAtCompileTime : 1,
|
||||||
|
OtherDerived::ColsAtCompileTime != Dynamic ? OtherDerived::ColsAtCompileTime : 1>
|
||||||
|
(m_row, m_col) = other;
|
||||||
|
else
|
||||||
|
m_xpr.block(m_row, m_col, other.rows(), other.cols()) = other;
|
||||||
m_col += other.cols();
|
m_col += other.cols();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline ~CommaInitializer()
|
inline ~CommaInitializer()
|
||||||
#if defined VERIFY_RAISES_ASSERT && (!defined EIGEN_NO_ASSERTION_CHECKING) && defined EIGEN_EXCEPTIONS
|
|
||||||
noexcept(false) // Eigen::eigen_assert_exception
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
finished();
|
eigen_assert((m_row+m_currentBlockRows) == m_xpr.rows()
|
||||||
|
&& m_col == m_xpr.cols()
|
||||||
|
&& "Too few coefficients passed to comma initializer (operator<<)");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the built matrix once all its coefficients have been set.
|
/** \returns the built matrix once all its coefficients have been set.
|
||||||
@@ -104,11 +113,7 @@ struct CommaInitializer {
|
|||||||
* quaternion.fromRotationMatrix((Matrix3f() << axis0, axis1, axis2).finished());
|
* quaternion.fromRotationMatrix((Matrix3f() << axis0, axis1, axis2).finished());
|
||||||
* \endcode
|
* \endcode
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC inline XprType& finished() {
|
inline XprType& finished() { return m_xpr; }
|
||||||
eigen_assert(((m_row + m_currentBlockRows) == m_xpr.rows() || m_xpr.cols() == 0) && m_col == m_xpr.cols() &&
|
|
||||||
"Too few coefficients passed to comma initializer (operator<<)");
|
|
||||||
return m_xpr;
|
|
||||||
}
|
|
||||||
|
|
||||||
XprType& m_xpr; // target expression
|
XprType& m_xpr; // target expression
|
||||||
Index m_row; // current row id
|
Index m_row; // current row id
|
||||||
@@ -125,24 +130,21 @@ struct CommaInitializer {
|
|||||||
* Example: \include MatrixBase_set.cpp
|
* Example: \include MatrixBase_set.cpp
|
||||||
* Output: \verbinclude MatrixBase_set.out
|
* Output: \verbinclude MatrixBase_set.out
|
||||||
*
|
*
|
||||||
* \note According the c++ standard, the argument expressions of this comma initializer are evaluated in arbitrary
|
|
||||||
* order.
|
|
||||||
*
|
|
||||||
* \sa CommaInitializer::finished(), class CommaInitializer
|
* \sa CommaInitializer::finished(), class CommaInitializer
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC inline CommaInitializer<Derived> DenseBase<Derived>::operator<<(const Scalar& s) {
|
inline CommaInitializer<Derived> DenseBase<Derived>::operator<< (const Scalar& s)
|
||||||
|
{
|
||||||
return CommaInitializer<Derived>(*static_cast<Derived*>(this), s);
|
return CommaInitializer<Derived>(*static_cast<Derived*>(this), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \sa operator<<(const Scalar&) */
|
/** \sa operator<<(const Scalar&) */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC inline CommaInitializer<Derived> DenseBase<Derived>::operator<<(
|
inline CommaInitializer<Derived>
|
||||||
const DenseBase<OtherDerived>& other) {
|
DenseBase<Derived>::operator<<(const DenseBase<OtherDerived>& other)
|
||||||
|
{
|
||||||
return CommaInitializer<Derived>(*static_cast<Derived *>(this), other);
|
return CommaInitializer<Derived>(*static_cast<Derived *>(this), other);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_COMMAINITIALIZER_H
|
#endif // EIGEN_COMMAINITIALIZER_H
|
||||||
|
|||||||
@@ -1,164 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2016 Rasmus Munk Larsen (rmlarsen@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_CONDITIONESTIMATOR_H
|
|
||||||
#define EIGEN_CONDITIONESTIMATOR_H
|
|
||||||
|
|
||||||
// IWYU pragma: private
|
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template <typename Vector, typename RealVector, bool IsComplex>
|
|
||||||
struct rcond_compute_sign {
|
|
||||||
static inline Vector run(const Vector& v) {
|
|
||||||
const RealVector v_abs = v.cwiseAbs();
|
|
||||||
return (v_abs.array() == static_cast<typename Vector::RealScalar>(0))
|
|
||||||
.select(Vector::Ones(v.size()), v.cwiseQuotient(v_abs));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Partial specialization to avoid elementwise division for real vectors.
|
|
||||||
template <typename Vector>
|
|
||||||
struct rcond_compute_sign<Vector, Vector, false> {
|
|
||||||
static inline Vector run(const Vector& v) {
|
|
||||||
return (v.array() < static_cast<typename Vector::RealScalar>(0))
|
|
||||||
.select(-Vector::Ones(v.size()), Vector::Ones(v.size()));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \returns an estimate of ||inv(matrix)||_1 given a decomposition of
|
|
||||||
* \a matrix that implements .solve() and .adjoint().solve() methods.
|
|
||||||
*
|
|
||||||
* This function implements Algorithms 4.1 and 5.1 from
|
|
||||||
* Higham, "Experience with a Matrix Norm Estimator",
|
|
||||||
* SIAM J. Sci. Stat. Comput., 11(4):804-809, 1990.
|
|
||||||
* with Higham's alternating-sign safety-net estimate from
|
|
||||||
* Higham and Tisseur, "A Block Algorithm for Matrix 1-Norm Estimation,
|
|
||||||
* with an Application to 1-Norm Pseudospectra", SIAM J. Matrix Anal. Appl.,
|
|
||||||
* 21(4):1185-1201, 2000.
|
|
||||||
*
|
|
||||||
* The Hager/Higham gradient ascent uses at most 5 iterations of 2 solves
|
|
||||||
* each, giving a total cost of O(n^2).
|
|
||||||
*
|
|
||||||
* Supports the following decompositions: FullPivLU, PartialPivLU, LDLT, LLT.
|
|
||||||
*
|
|
||||||
* \sa FullPivLU, PartialPivLU, LDLT, LLT.
|
|
||||||
*/
|
|
||||||
template <typename Decomposition>
|
|
||||||
typename Decomposition::RealScalar rcond_invmatrix_L1_norm_estimate(const Decomposition& dec) {
|
|
||||||
typedef typename Decomposition::MatrixType MatrixType;
|
|
||||||
typedef typename Decomposition::Scalar Scalar;
|
|
||||||
typedef typename Decomposition::RealScalar RealScalar;
|
|
||||||
typedef typename internal::plain_col_type<MatrixType>::type Vector;
|
|
||||||
typedef typename internal::plain_col_type<MatrixType, RealScalar>::type RealVector;
|
|
||||||
const bool is_complex = (NumTraits<Scalar>::IsComplex != 0);
|
|
||||||
|
|
||||||
eigen_assert(dec.rows() == dec.cols());
|
|
||||||
const Index n = dec.rows();
|
|
||||||
if (n == 0) return RealScalar(0);
|
|
||||||
|
|
||||||
// Disable Index to float conversion warning
|
|
||||||
#ifdef __INTEL_COMPILER
|
|
||||||
#pragma warning push
|
|
||||||
#pragma warning(disable : 2259)
|
|
||||||
#endif
|
|
||||||
Vector v = dec.solve(Vector::Ones(n) / Scalar(n));
|
|
||||||
#ifdef __INTEL_COMPILER
|
|
||||||
#pragma warning pop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// lower_bound is a lower bound on
|
|
||||||
// ||inv(matrix)||_1 = sup_v ||inv(matrix) v||_1 / ||v||_1
|
|
||||||
// and is the objective maximized by the supergradient ascent algorithm below.
|
|
||||||
RealScalar lower_bound = v.template lpNorm<1>();
|
|
||||||
if (n == 1) return lower_bound;
|
|
||||||
|
|
||||||
// Gradient ascent: the optimum is achieved at a unit vector e_j. Each
|
|
||||||
// iteration follows the supergradient to find which unit vector to probe next.
|
|
||||||
RealScalar old_lower_bound = lower_bound;
|
|
||||||
Vector sign_vector(n);
|
|
||||||
Vector old_sign_vector;
|
|
||||||
Index v_max_abs_index = -1;
|
|
||||||
Index old_v_max_abs_index = v_max_abs_index;
|
|
||||||
for (int k = 0; k < 4; ++k) {
|
|
||||||
sign_vector = internal::rcond_compute_sign<Vector, RealVector, is_complex>::run(v);
|
|
||||||
if (k > 0 && !is_complex && sign_vector == old_sign_vector) {
|
|
||||||
// Break if the sign vector stagnated.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// Supergradient: z = A^{-T} * sign(v), pick argmax |z_i|.
|
|
||||||
v = dec.adjoint().solve(sign_vector);
|
|
||||||
v.real().cwiseAbs().maxCoeff(&v_max_abs_index);
|
|
||||||
if (v_max_abs_index == old_v_max_abs_index) {
|
|
||||||
// Optimality: supergradient points to the same unit vector.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// Probe the best unit vector: v = A^{-1} * e_j.
|
|
||||||
v = dec.solve(Vector::Unit(n, v_max_abs_index));
|
|
||||||
lower_bound = v.template lpNorm<1>();
|
|
||||||
if (lower_bound <= old_lower_bound) {
|
|
||||||
// No improvement from the gradient step.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!is_complex) {
|
|
||||||
old_sign_vector = sign_vector;
|
|
||||||
}
|
|
||||||
old_v_max_abs_index = v_max_abs_index;
|
|
||||||
old_lower_bound = lower_bound;
|
|
||||||
}
|
|
||||||
// Higham's alternating-sign estimate: an independent safety-net that catches
|
|
||||||
// cases where the gradient ascent converges to a local maximum due to exact
|
|
||||||
// cancellation patterns (especially with permutations and backsubstitutions).
|
|
||||||
// v_i = (-1)^i * (1 + i/(n-1)), then estimate = 2*||A^{-1}*v||_1 / (3*n).
|
|
||||||
Scalar alternating_sign(RealScalar(1));
|
|
||||||
for (Index i = 0; i < n; ++i) {
|
|
||||||
// The static_cast is needed when Scalar is complex and RealScalar uses expression templates.
|
|
||||||
v[i] = alternating_sign * static_cast<RealScalar>(RealScalar(1) + (RealScalar(i) / (RealScalar(n - 1))));
|
|
||||||
alternating_sign = -alternating_sign;
|
|
||||||
}
|
|
||||||
v = dec.solve(v);
|
|
||||||
const RealScalar alt_est = (RealScalar(2) * v.template lpNorm<1>()) / (RealScalar(3) * RealScalar(n));
|
|
||||||
return numext::maxi(lower_bound, alt_est);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief Reciprocal condition number estimator.
|
|
||||||
*
|
|
||||||
* Computing a decomposition of a dense matrix takes O(n^3) operations, while
|
|
||||||
* this method estimates the condition number quickly and reliably in O(n^2)
|
|
||||||
* operations.
|
|
||||||
*
|
|
||||||
* \returns an estimate of the reciprocal condition number
|
|
||||||
* (1 / (||matrix||_1 * ||inv(matrix)||_1)) of matrix, given ||matrix||_1 and
|
|
||||||
* its decomposition. Supports the following decompositions: FullPivLU,
|
|
||||||
* PartialPivLU, LDLT, and LLT.
|
|
||||||
*
|
|
||||||
* \sa FullPivLU, PartialPivLU, LDLT, LLT.
|
|
||||||
*/
|
|
||||||
template <typename Decomposition>
|
|
||||||
typename Decomposition::RealScalar rcond_estimate_helper(typename Decomposition::RealScalar matrix_norm,
|
|
||||||
const Decomposition& dec) {
|
|
||||||
typedef typename Decomposition::RealScalar RealScalar;
|
|
||||||
eigen_assert(dec.rows() == dec.cols());
|
|
||||||
if (dec.rows() == 0) return NumTraits<RealScalar>::infinity();
|
|
||||||
if (numext::is_exactly_zero(matrix_norm)) return RealScalar(0);
|
|
||||||
if (dec.rows() == 1) return RealScalar(1);
|
|
||||||
const RealScalar inverse_matrix_norm = rcond_invmatrix_L1_norm_estimate(dec);
|
|
||||||
return (numext::is_exactly_zero(inverse_matrix_norm) ? RealScalar(0)
|
|
||||||
: (RealScalar(1) / inverse_matrix_norm) / matrix_norm);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
} // namespace Eigen
|
|
||||||
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,141 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
|
|
||||||
//
|
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
#ifndef EIGEN_COREITERATORS_H
|
|
||||||
#define EIGEN_COREITERATORS_H
|
|
||||||
|
|
||||||
// IWYU pragma: private
|
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
/* This file contains the respective InnerIterator definition of the expressions defined in Eigen/Core
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template <typename XprType, typename EvaluatorKind>
|
|
||||||
class inner_iterator_selector;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \class InnerIterator
|
|
||||||
* \brief An InnerIterator allows to loop over the element of any matrix expression.
|
|
||||||
*
|
|
||||||
* \warning To be used with care because an evaluator is constructed every time an InnerIterator iterator is
|
|
||||||
* constructed.
|
|
||||||
*
|
|
||||||
* TODO: add a usage example
|
|
||||||
*/
|
|
||||||
template <typename XprType>
|
|
||||||
class InnerIterator {
|
|
||||||
protected:
|
|
||||||
typedef internal::inner_iterator_selector<XprType, typename internal::evaluator_traits<XprType>::Kind> IteratorType;
|
|
||||||
typedef internal::evaluator<XprType> EvaluatorType;
|
|
||||||
typedef typename internal::traits<XprType>::Scalar Scalar;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/** Construct an iterator over the \a outerId -th row or column of \a xpr */
|
|
||||||
InnerIterator(const XprType &xpr, const Index &outerId) : m_eval(xpr), m_iter(m_eval, outerId, xpr.innerSize()) {}
|
|
||||||
|
|
||||||
/// \returns the value of the current coefficient.
|
|
||||||
EIGEN_STRONG_INLINE Scalar value() const { return m_iter.value(); }
|
|
||||||
/** Increment the iterator \c *this to the next non-zero coefficient.
|
|
||||||
* Explicit zeros are not skipped over. To skip explicit zeros, see class SparseView
|
|
||||||
*/
|
|
||||||
EIGEN_STRONG_INLINE InnerIterator &operator++() {
|
|
||||||
m_iter.operator++();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
EIGEN_STRONG_INLINE InnerIterator &operator+=(Index i) {
|
|
||||||
m_iter.operator+=(i);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
EIGEN_STRONG_INLINE InnerIterator operator+(Index i) const {
|
|
||||||
InnerIterator result(*this);
|
|
||||||
result += i;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \returns the column or row index of the current coefficient.
|
|
||||||
EIGEN_STRONG_INLINE Index index() const { return m_iter.index(); }
|
|
||||||
/// \returns the row index of the current coefficient.
|
|
||||||
EIGEN_STRONG_INLINE Index row() const { return m_iter.row(); }
|
|
||||||
/// \returns the column index of the current coefficient.
|
|
||||||
EIGEN_STRONG_INLINE Index col() const { return m_iter.col(); }
|
|
||||||
/// \returns \c true if the iterator \c *this still references a valid coefficient.
|
|
||||||
EIGEN_STRONG_INLINE operator bool() const { return m_iter; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
EvaluatorType m_eval;
|
|
||||||
IteratorType m_iter;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// If you get here, then you're not using the right InnerIterator type, e.g.:
|
|
||||||
// SparseMatrix<double,RowMajor> A;
|
|
||||||
// SparseMatrix<double>::InnerIterator it(A,0);
|
|
||||||
template <typename T>
|
|
||||||
InnerIterator(const EigenBase<T> &, Index outer);
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
// Generic inner iterator implementation for dense objects
|
|
||||||
template <typename XprType>
|
|
||||||
class inner_iterator_selector<XprType, IndexBased> {
|
|
||||||
protected:
|
|
||||||
typedef evaluator<XprType> EvaluatorType;
|
|
||||||
typedef typename traits<XprType>::Scalar Scalar;
|
|
||||||
enum { IsRowMajor = (XprType::Flags & RowMajorBit) == RowMajorBit };
|
|
||||||
|
|
||||||
public:
|
|
||||||
EIGEN_STRONG_INLINE inner_iterator_selector(const EvaluatorType &eval, const Index &outerId, const Index &innerSize)
|
|
||||||
: m_eval(eval), m_inner(0), m_outer(outerId), m_end(innerSize) {}
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE Scalar value() const {
|
|
||||||
return (IsRowMajor) ? m_eval.coeff(m_outer, m_inner) : m_eval.coeff(m_inner, m_outer);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE inner_iterator_selector &operator++() {
|
|
||||||
m_inner++;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE Index index() const { return m_inner; }
|
|
||||||
inline Index row() const { return IsRowMajor ? m_outer : index(); }
|
|
||||||
inline Index col() const { return IsRowMajor ? index() : m_outer; }
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE operator bool() const { return m_inner < m_end && m_inner >= 0; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const EvaluatorType &m_eval;
|
|
||||||
Index m_inner;
|
|
||||||
const Index m_outer;
|
|
||||||
const Index m_end;
|
|
||||||
};
|
|
||||||
|
|
||||||
// For iterator-based evaluator, inner-iterator is already implemented as
|
|
||||||
// evaluator<>::InnerIterator
|
|
||||||
template <typename XprType>
|
|
||||||
class inner_iterator_selector<XprType, IteratorBased> : public evaluator<XprType>::InnerIterator {
|
|
||||||
protected:
|
|
||||||
typedef typename evaluator<XprType>::InnerIterator Base;
|
|
||||||
typedef evaluator<XprType> EvaluatorType;
|
|
||||||
|
|
||||||
public:
|
|
||||||
EIGEN_STRONG_INLINE inner_iterator_selector(const EvaluatorType &eval, const Index &outerId,
|
|
||||||
const Index & /*innerSize*/)
|
|
||||||
: Base(eval, outerId) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_COREITERATORS_H
|
|
||||||
@@ -1,27 +1,58 @@
|
|||||||
// 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-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
|
// Copyright (C) 2008-2009 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
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_CWISE_BINARY_OP_H
|
#ifndef EIGEN_CWISE_BINARY_OP_H
|
||||||
#define EIGEN_CWISE_BINARY_OP_H
|
#define EIGEN_CWISE_BINARY_OP_H
|
||||||
|
|
||||||
// IWYU pragma: private
|
/** \class CwiseBinaryOp
|
||||||
#include "./InternalHeaderCheck.h"
|
* \ingroup Core_Module
|
||||||
|
*
|
||||||
namespace Eigen {
|
* \brief Generic expression where a coefficient-wise binary operator is applied to two expressions
|
||||||
|
*
|
||||||
|
* \param BinaryOp template functor implementing the operator
|
||||||
|
* \param Lhs the type of the left-hand side
|
||||||
|
* \param Rhs the type of the right-hand side
|
||||||
|
*
|
||||||
|
* This class represents an expression where a coefficient-wise binary operator is applied to two expressions.
|
||||||
|
* It is the return type of binary operators, by which we mean only those binary operators where
|
||||||
|
* both the left-hand side and the right-hand side are Eigen expressions.
|
||||||
|
* For example, the return type of matrix1+matrix2 is a CwiseBinaryOp.
|
||||||
|
*
|
||||||
|
* Most of the time, this is the only way that it is used, so you typically don't have to name
|
||||||
|
* CwiseBinaryOp types explicitly.
|
||||||
|
*
|
||||||
|
* \sa MatrixBase::binaryExpr(const MatrixBase<OtherDerived> &,const CustomBinaryOp &) const, class CwiseUnaryOp, class CwiseNullaryOp
|
||||||
|
*/
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
template<typename BinaryOp, typename Lhs, typename Rhs>
|
template<typename BinaryOp, typename Lhs, typename Rhs>
|
||||||
struct traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs>> {
|
struct traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
|
||||||
|
{
|
||||||
// we must not inherit from traits<Lhs> since it has
|
// we must not inherit from traits<Lhs> since it has
|
||||||
// the potential to cause problems with MSVC
|
// the potential to cause problems with MSVC
|
||||||
typedef remove_all_t<Lhs> Ancestor;
|
typedef typename remove_all<Lhs>::type Ancestor;
|
||||||
typedef typename traits<Ancestor>::XprKind XprKind;
|
typedef typename traits<Ancestor>::XprKind XprKind;
|
||||||
enum {
|
enum {
|
||||||
RowsAtCompileTime = traits<Ancestor>::RowsAtCompileTime,
|
RowsAtCompileTime = traits<Ancestor>::RowsAtCompileTime,
|
||||||
@@ -32,111 +63,150 @@ struct traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs>> {
|
|||||||
|
|
||||||
// even though we require Lhs and Rhs to have the same scalar type (see CwiseBinaryOp constructor),
|
// even though we require Lhs and Rhs to have the same scalar type (see CwiseBinaryOp constructor),
|
||||||
// we still want to handle the case when the result type is different.
|
// we still want to handle the case when the result type is different.
|
||||||
typedef typename result_of<BinaryOp(const typename Lhs::Scalar&, const typename Rhs::Scalar&)>::type Scalar;
|
typedef typename result_of<
|
||||||
typedef typename cwise_promote_storage_type<typename traits<Lhs>::StorageKind, typename traits<Rhs>::StorageKind,
|
BinaryOp(
|
||||||
BinaryOp>::ret StorageKind;
|
typename Lhs::Scalar,
|
||||||
typedef typename promote_index_type<typename traits<Lhs>::StorageIndex, typename traits<Rhs>::StorageIndex>::type
|
typename Rhs::Scalar
|
||||||
StorageIndex;
|
)
|
||||||
|
>::type Scalar;
|
||||||
|
typedef typename promote_storage_type<typename traits<Lhs>::StorageKind,
|
||||||
|
typename traits<Rhs>::StorageKind>::ret StorageKind;
|
||||||
|
typedef typename promote_index_type<typename traits<Lhs>::Index,
|
||||||
|
typename traits<Rhs>::Index>::type Index;
|
||||||
typedef typename Lhs::Nested LhsNested;
|
typedef typename Lhs::Nested LhsNested;
|
||||||
typedef typename Rhs::Nested RhsNested;
|
typedef typename Rhs::Nested RhsNested;
|
||||||
typedef std::remove_reference_t<LhsNested> LhsNested_;
|
typedef typename remove_reference<LhsNested>::type _LhsNested;
|
||||||
typedef std::remove_reference_t<RhsNested> RhsNested_;
|
typedef typename remove_reference<RhsNested>::type _RhsNested;
|
||||||
enum {
|
enum {
|
||||||
Flags = cwise_promote_storage_order<typename traits<Lhs>::StorageKind, typename traits<Rhs>::StorageKind,
|
LhsCoeffReadCost = _LhsNested::CoeffReadCost,
|
||||||
LhsNested_::Flags & RowMajorBit, RhsNested_::Flags & RowMajorBit>::value
|
RhsCoeffReadCost = _RhsNested::CoeffReadCost,
|
||||||
|
LhsFlags = _LhsNested::Flags,
|
||||||
|
RhsFlags = _RhsNested::Flags,
|
||||||
|
SameType = is_same<typename _LhsNested::Scalar,typename _RhsNested::Scalar>::value,
|
||||||
|
StorageOrdersAgree = (int(Lhs::Flags)&RowMajorBit)==(int(Rhs::Flags)&RowMajorBit),
|
||||||
|
Flags0 = (int(LhsFlags) | int(RhsFlags)) & (
|
||||||
|
HereditaryBits
|
||||||
|
| (int(LhsFlags) & int(RhsFlags) &
|
||||||
|
( AlignedBit
|
||||||
|
| (StorageOrdersAgree ? LinearAccessBit : 0)
|
||||||
|
| (functor_traits<BinaryOp>::PacketAccess && StorageOrdersAgree && SameType ? PacketAccessBit : 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Flags = (Flags0 & ~RowMajorBit) | (LhsFlags & RowMajorBit),
|
||||||
|
CoeffReadCost = LhsCoeffReadCost + RhsCoeffReadCost + functor_traits<BinaryOp>::Cost
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
|
// we require Lhs and Rhs to have the same scalar type. Currently there is no example of a binary functor
|
||||||
|
// that would take two operands of different types. If there were such an example, then this check should be
|
||||||
|
// moved to the BinaryOp functors, on a per-case basis. This would however require a change in the BinaryOp functors, as
|
||||||
|
// currently they take only one typename Scalar template parameter.
|
||||||
|
// It is tempting to always allow mixing different types but remember that this is often impossible in the vectorized paths.
|
||||||
|
// So allowing mixing different types gives very unexpected errors when enabling vectorization, when the user tries to
|
||||||
|
// add together a float matrix and a double matrix.
|
||||||
|
#define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \
|
||||||
|
EIGEN_STATIC_ASSERT((internal::functor_allows_mixing_real_and_complex<BINOP>::ret \
|
||||||
|
? int(internal::is_same<typename NumTraits<LHS>::Real, typename NumTraits<RHS>::Real>::value) \
|
||||||
|
: int(internal::is_same<LHS, RHS>::value)), \
|
||||||
|
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||||
|
|
||||||
template<typename BinaryOp, typename Lhs, typename Rhs, typename StorageKind>
|
template<typename BinaryOp, typename Lhs, typename Rhs, typename StorageKind>
|
||||||
class CwiseBinaryOpImpl;
|
class CwiseBinaryOpImpl;
|
||||||
|
|
||||||
/** \class CwiseBinaryOp
|
template<typename BinaryOp, typename Lhs, typename Rhs>
|
||||||
* \ingroup Core_Module
|
class CwiseBinaryOp : internal::no_assignment_operator,
|
||||||
*
|
public CwiseBinaryOpImpl<
|
||||||
* \brief Generic expression where a coefficient-wise binary operator is applied to two expressions
|
BinaryOp, Lhs, Rhs,
|
||||||
*
|
typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind,
|
||||||
* \tparam BinaryOp template functor implementing the operator
|
typename internal::traits<Rhs>::StorageKind>::ret>
|
||||||
* \tparam LhsType the type of the left-hand side
|
{
|
||||||
* \tparam RhsType the type of the right-hand side
|
|
||||||
*
|
|
||||||
* This class represents an expression where a coefficient-wise binary operator is applied to two expressions.
|
|
||||||
* It is the return type of binary operators, by which we mean only those binary operators where
|
|
||||||
* both the left-hand side and the right-hand side are Eigen expressions.
|
|
||||||
* For example, the return type of matrix1+matrix2 is a CwiseBinaryOp.
|
|
||||||
*
|
|
||||||
* Most of the time, this is the only way that it is used, so you typically don't have to name
|
|
||||||
* CwiseBinaryOp types explicitly.
|
|
||||||
*
|
|
||||||
* \sa MatrixBase::binaryExpr(const MatrixBase<OtherDerived> &,const CustomBinaryOp &) const, class CwiseUnaryOp, class
|
|
||||||
* CwiseNullaryOp
|
|
||||||
*/
|
|
||||||
template <typename BinaryOp, typename LhsType, typename RhsType>
|
|
||||||
class CwiseBinaryOp : public CwiseBinaryOpImpl<BinaryOp, LhsType, RhsType,
|
|
||||||
typename internal::cwise_promote_storage_type<
|
|
||||||
typename internal::traits<LhsType>::StorageKind,
|
|
||||||
typename internal::traits<RhsType>::StorageKind, BinaryOp>::ret>,
|
|
||||||
internal::no_assignment_operator {
|
|
||||||
public:
|
public:
|
||||||
typedef internal::remove_all_t<BinaryOp> Functor;
|
|
||||||
typedef internal::remove_all_t<LhsType> Lhs;
|
|
||||||
typedef internal::remove_all_t<RhsType> Rhs;
|
|
||||||
|
|
||||||
typedef typename CwiseBinaryOpImpl<
|
typedef typename CwiseBinaryOpImpl<
|
||||||
BinaryOp, LhsType, RhsType,
|
BinaryOp, Lhs, Rhs,
|
||||||
typename internal::cwise_promote_storage_type<typename internal::traits<LhsType>::StorageKind,
|
typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind,
|
||||||
typename internal::traits<Rhs>::StorageKind, BinaryOp>::ret>::Base
|
typename internal::traits<Rhs>::StorageKind>::ret>::Base Base;
|
||||||
Base;
|
|
||||||
EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseBinaryOp)
|
EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseBinaryOp)
|
||||||
|
|
||||||
EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp, typename Lhs::Scalar, typename Rhs::Scalar)
|
typedef typename internal::nested<Lhs>::type LhsNested;
|
||||||
|
typedef typename internal::nested<Rhs>::type RhsNested;
|
||||||
|
typedef typename internal::remove_reference<LhsNested>::type _LhsNested;
|
||||||
|
typedef typename internal::remove_reference<RhsNested>::type _RhsNested;
|
||||||
|
|
||||||
|
EIGEN_STRONG_INLINE CwiseBinaryOp(const Lhs& lhs, const Rhs& rhs, const BinaryOp& func = BinaryOp())
|
||||||
|
: m_lhs(lhs), m_rhs(rhs), m_functor(func)
|
||||||
|
{
|
||||||
|
EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename Rhs::Scalar);
|
||||||
|
// require the sizes to match
|
||||||
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs, Rhs)
|
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs, Rhs)
|
||||||
|
eigen_assert(lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols());
|
||||||
typedef typename internal::ref_selector<LhsType>::type LhsNested;
|
|
||||||
typedef typename internal::ref_selector<RhsType>::type RhsNested;
|
|
||||||
typedef std::remove_reference_t<LhsNested> LhsNested_;
|
|
||||||
typedef std::remove_reference_t<RhsNested> RhsNested_;
|
|
||||||
|
|
||||||
#if EIGEN_COMP_MSVC
|
|
||||||
// Required for Visual Studio, which may fail to inline the copy constructor otherwise.
|
|
||||||
EIGEN_STRONG_INLINE CwiseBinaryOp(const CwiseBinaryOp<BinaryOp, LhsType, RhsType>&) = default;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE CwiseBinaryOp(const Lhs& aLhs, const Rhs& aRhs,
|
|
||||||
const BinaryOp& func = BinaryOp())
|
|
||||||
: m_lhs(aLhs), m_rhs(aRhs), m_functor(func) {
|
|
||||||
eigen_assert(aLhs.rows() == aRhs.rows() && aLhs.cols() == aRhs.cols());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index rows() const 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<internal::remove_all_t<LhsNested>>::RowsAtCompileTime == Dynamic ? m_rhs.rows()
|
if (internal::traits<typename internal::remove_all<LhsNested>::type>::RowsAtCompileTime==Dynamic)
|
||||||
: m_lhs.rows();
|
return m_rhs.rows();
|
||||||
|
else
|
||||||
|
return m_lhs.rows();
|
||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC constexpr Index cols() const 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<internal::remove_all_t<LhsNested>>::ColsAtCompileTime == Dynamic ? m_rhs.cols()
|
if (internal::traits<typename internal::remove_all<LhsNested>::type>::ColsAtCompileTime==Dynamic)
|
||||||
: m_lhs.cols();
|
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 constexpr EIGEN_STRONG_INLINE 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 constexpr EIGEN_STRONG_INLINE 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 constexpr EIGEN_STRONG_INLINE const BinaryOp& functor() const { return m_functor; }
|
const BinaryOp& functor() const { return m_functor; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
LhsNested m_lhs;
|
const LhsNested m_lhs;
|
||||||
RhsNested m_rhs;
|
const RhsNested m_rhs;
|
||||||
const BinaryOp m_functor;
|
const BinaryOp m_functor;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generic API dispatcher
|
template<typename BinaryOp, typename Lhs, typename Rhs>
|
||||||
template <typename BinaryOp, typename Lhs, typename Rhs, typename StorageKind>
|
class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Dense>
|
||||||
class CwiseBinaryOpImpl : public internal::generic_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs>>::type {
|
: public internal::dense_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type
|
||||||
|
{
|
||||||
|
typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> Derived;
|
||||||
public:
|
public:
|
||||||
typedef typename internal::generic_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs>>::type Base;
|
|
||||||
|
typedef typename internal::dense_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type Base;
|
||||||
|
EIGEN_DENSE_PUBLIC_INTERFACE( Derived )
|
||||||
|
|
||||||
|
EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const
|
||||||
|
{
|
||||||
|
return derived().functor()(derived().lhs().coeff(row, col),
|
||||||
|
derived().rhs().coeff(row, col));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
|
||||||
|
{
|
||||||
|
return derived().functor().packetOp(derived().lhs().template packet<LoadMode>(row, col),
|
||||||
|
derived().rhs().template packet<LoadMode>(row, col));
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
|
||||||
|
{
|
||||||
|
return derived().functor()(derived().lhs().coeff(index),
|
||||||
|
derived().rhs().coeff(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
|
||||||
|
{
|
||||||
|
return derived().functor().packetOp(derived().lhs().template packet<LoadMode>(index),
|
||||||
|
derived().rhs().template packet<LoadMode>(index));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** replaces \c *this by \c *this - \a other.
|
/** replaces \c *this by \c *this - \a other.
|
||||||
@@ -145,8 +215,11 @@ class CwiseBinaryOpImpl : public internal::generic_xpr_base<CwiseBinaryOp<Binary
|
|||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Derived& MatrixBase<Derived>::operator-=(const MatrixBase<OtherDerived>& other) {
|
EIGEN_STRONG_INLINE Derived &
|
||||||
call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar, typename OtherDerived::Scalar>());
|
MatrixBase<Derived>::operator-=(const MatrixBase<OtherDerived> &other)
|
||||||
|
{
|
||||||
|
SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, Derived, OtherDerived> tmp(derived());
|
||||||
|
tmp = other.derived();
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,11 +229,12 @@ EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Derived& MatrixBase<Derived>::operator-=(c
|
|||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Derived& MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other) {
|
EIGEN_STRONG_INLINE Derived &
|
||||||
call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar, typename OtherDerived::Scalar>());
|
MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other)
|
||||||
|
{
|
||||||
|
SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, Derived, OtherDerived> tmp(derived());
|
||||||
|
tmp = other.derived();
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_CWISE_BINARY_OP_H
|
#endif // EIGEN_CWISE_BINARY_OP_H
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,171 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
|
|
||||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
|
||||||
// Copyright (C) 2016 Eugene Brevdo <ebrevdo@gmail.com>
|
|
||||||
//
|
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
#ifndef EIGEN_CWISE_TERNARY_OP_H
|
|
||||||
#define EIGEN_CWISE_TERNARY_OP_H
|
|
||||||
|
|
||||||
// IWYU pragma: private
|
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
template <typename TernaryOp, typename Arg1, typename Arg2, typename Arg3>
|
|
||||||
struct traits<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>> {
|
|
||||||
// we must not inherit from traits<Arg1> since it has
|
|
||||||
// the potential to cause problems with MSVC
|
|
||||||
typedef remove_all_t<Arg1> Ancestor;
|
|
||||||
typedef typename traits<Ancestor>::XprKind XprKind;
|
|
||||||
enum {
|
|
||||||
RowsAtCompileTime = traits<Ancestor>::RowsAtCompileTime,
|
|
||||||
ColsAtCompileTime = traits<Ancestor>::ColsAtCompileTime,
|
|
||||||
MaxRowsAtCompileTime = traits<Ancestor>::MaxRowsAtCompileTime,
|
|
||||||
MaxColsAtCompileTime = traits<Ancestor>::MaxColsAtCompileTime
|
|
||||||
};
|
|
||||||
|
|
||||||
// even though we require Arg1, Arg2, and Arg3 to have the same scalar type
|
|
||||||
// (see CwiseTernaryOp constructor),
|
|
||||||
// we still want to handle the case when the result type is different.
|
|
||||||
typedef typename result_of<TernaryOp(const typename Arg1::Scalar&, const typename Arg2::Scalar&,
|
|
||||||
const typename Arg3::Scalar&)>::type Scalar;
|
|
||||||
|
|
||||||
typedef typename internal::traits<Arg1>::StorageKind StorageKind;
|
|
||||||
typedef typename internal::traits<Arg1>::StorageIndex StorageIndex;
|
|
||||||
|
|
||||||
typedef typename Arg1::Nested Arg1Nested;
|
|
||||||
typedef typename Arg2::Nested Arg2Nested;
|
|
||||||
typedef typename Arg3::Nested Arg3Nested;
|
|
||||||
typedef std::remove_reference_t<Arg1Nested> Arg1Nested_;
|
|
||||||
typedef std::remove_reference_t<Arg2Nested> Arg2Nested_;
|
|
||||||
typedef std::remove_reference_t<Arg3Nested> Arg3Nested_;
|
|
||||||
enum { Flags = Arg1Nested_::Flags & RowMajorBit };
|
|
||||||
};
|
|
||||||
} // end namespace internal
|
|
||||||
|
|
||||||
template <typename TernaryOp, typename Arg1, typename Arg2, typename Arg3, typename StorageKind>
|
|
||||||
class CwiseTernaryOpImpl;
|
|
||||||
|
|
||||||
/** \class CwiseTernaryOp
|
|
||||||
* \ingroup Core_Module
|
|
||||||
*
|
|
||||||
* \brief Generic expression where a coefficient-wise ternary operator is
|
|
||||||
* applied to two expressions
|
|
||||||
*
|
|
||||||
* \tparam TernaryOp template functor implementing the operator
|
|
||||||
* \tparam Arg1Type the type of the first argument
|
|
||||||
* \tparam Arg2Type the type of the second argument
|
|
||||||
* \tparam Arg3Type the type of the third argument
|
|
||||||
*
|
|
||||||
* This class represents an expression where a coefficient-wise ternary
|
|
||||||
* operator is applied to three expressions.
|
|
||||||
* It is the return type of ternary operators, by which we mean only those
|
|
||||||
* ternary operators where
|
|
||||||
* all three arguments are Eigen expressions.
|
|
||||||
* For example, the return type of betainc(matrix1, matrix2, matrix3) is a
|
|
||||||
* CwiseTernaryOp.
|
|
||||||
*
|
|
||||||
* Most of the time, this is the only way that it is used, so you typically
|
|
||||||
* don't have to name
|
|
||||||
* CwiseTernaryOp types explicitly.
|
|
||||||
*
|
|
||||||
* \sa MatrixBase::ternaryExpr(const MatrixBase<Argument2> &, const
|
|
||||||
* MatrixBase<Argument3> &, const CustomTernaryOp &) const, class CwiseBinaryOp,
|
|
||||||
* class CwiseUnaryOp, class CwiseNullaryOp
|
|
||||||
*/
|
|
||||||
template <typename TernaryOp, typename Arg1Type, typename Arg2Type, typename Arg3Type>
|
|
||||||
class CwiseTernaryOp : public CwiseTernaryOpImpl<TernaryOp, Arg1Type, Arg2Type, Arg3Type,
|
|
||||||
typename internal::traits<Arg1Type>::StorageKind>,
|
|
||||||
internal::no_assignment_operator {
|
|
||||||
public:
|
|
||||||
typedef internal::remove_all_t<Arg1Type> Arg1;
|
|
||||||
typedef internal::remove_all_t<Arg2Type> Arg2;
|
|
||||||
typedef internal::remove_all_t<Arg3Type> Arg3;
|
|
||||||
|
|
||||||
// require the sizes to match
|
|
||||||
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Arg1, Arg2)
|
|
||||||
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Arg1, Arg3)
|
|
||||||
|
|
||||||
// The index types should match
|
|
||||||
EIGEN_STATIC_ASSERT((internal::is_same<typename internal::traits<Arg1Type>::StorageKind,
|
|
||||||
typename internal::traits<Arg2Type>::StorageKind>::value),
|
|
||||||
STORAGE_KIND_MUST_MATCH)
|
|
||||||
EIGEN_STATIC_ASSERT((internal::is_same<typename internal::traits<Arg1Type>::StorageKind,
|
|
||||||
typename internal::traits<Arg3Type>::StorageKind>::value),
|
|
||||||
STORAGE_KIND_MUST_MATCH)
|
|
||||||
|
|
||||||
typedef typename CwiseTernaryOpImpl<TernaryOp, Arg1Type, Arg2Type, Arg3Type,
|
|
||||||
typename internal::traits<Arg1Type>::StorageKind>::Base Base;
|
|
||||||
EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseTernaryOp)
|
|
||||||
|
|
||||||
typedef typename internal::ref_selector<Arg1Type>::type Arg1Nested;
|
|
||||||
typedef typename internal::ref_selector<Arg2Type>::type Arg2Nested;
|
|
||||||
typedef typename internal::ref_selector<Arg3Type>::type Arg3Nested;
|
|
||||||
typedef std::remove_reference_t<Arg1Nested> Arg1Nested_;
|
|
||||||
typedef std::remove_reference_t<Arg2Nested> Arg2Nested_;
|
|
||||||
typedef std::remove_reference_t<Arg3Nested> Arg3Nested_;
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CwiseTernaryOp(const Arg1& a1, const Arg2& a2, const Arg3& a3,
|
|
||||||
const TernaryOp& func = TernaryOp())
|
|
||||||
: m_arg1(a1), m_arg2(a2), m_arg3(a3), m_functor(func) {
|
|
||||||
eigen_assert(a1.rows() == a2.rows() && a1.cols() == a2.cols() && a1.rows() == a3.rows() && a1.cols() == a3.cols());
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Index rows() const {
|
|
||||||
// return the fixed size type if available to enable compile time
|
|
||||||
// optimizations
|
|
||||||
if (internal::traits<internal::remove_all_t<Arg1Nested>>::RowsAtCompileTime == Dynamic &&
|
|
||||||
internal::traits<internal::remove_all_t<Arg2Nested>>::RowsAtCompileTime == Dynamic)
|
|
||||||
return m_arg3.rows();
|
|
||||||
else if (internal::traits<internal::remove_all_t<Arg1Nested>>::RowsAtCompileTime == Dynamic &&
|
|
||||||
internal::traits<internal::remove_all_t<Arg3Nested>>::RowsAtCompileTime == Dynamic)
|
|
||||||
return m_arg2.rows();
|
|
||||||
else
|
|
||||||
return m_arg1.rows();
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Index cols() const {
|
|
||||||
// return the fixed size type if available to enable compile time
|
|
||||||
// optimizations
|
|
||||||
if (internal::traits<internal::remove_all_t<Arg1Nested>>::ColsAtCompileTime == Dynamic &&
|
|
||||||
internal::traits<internal::remove_all_t<Arg2Nested>>::ColsAtCompileTime == Dynamic)
|
|
||||||
return m_arg3.cols();
|
|
||||||
else if (internal::traits<internal::remove_all_t<Arg1Nested>>::ColsAtCompileTime == Dynamic &&
|
|
||||||
internal::traits<internal::remove_all_t<Arg3Nested>>::ColsAtCompileTime == Dynamic)
|
|
||||||
return m_arg2.cols();
|
|
||||||
else
|
|
||||||
return m_arg1.cols();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \returns the first argument nested expression */
|
|
||||||
EIGEN_DEVICE_FUNC constexpr const Arg1Nested_& arg1() const { return m_arg1; }
|
|
||||||
/** \returns the first argument nested expression */
|
|
||||||
EIGEN_DEVICE_FUNC constexpr const Arg2Nested_& arg2() const { return m_arg2; }
|
|
||||||
/** \returns the third argument nested expression */
|
|
||||||
EIGEN_DEVICE_FUNC constexpr const Arg3Nested_& arg3() const { return m_arg3; }
|
|
||||||
/** \returns the functor representing the ternary operation */
|
|
||||||
EIGEN_DEVICE_FUNC constexpr const TernaryOp& functor() const { return m_functor; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Arg1Nested m_arg1;
|
|
||||||
Arg2Nested m_arg2;
|
|
||||||
Arg3Nested m_arg3;
|
|
||||||
const TernaryOp m_functor;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Generic API dispatcher
|
|
||||||
template <typename TernaryOp, typename Arg1, typename Arg2, typename Arg3, typename StorageKind>
|
|
||||||
class CwiseTernaryOpImpl : public internal::generic_xpr_base<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>>::type {
|
|
||||||
public:
|
|
||||||
typedef typename internal::generic_xpr_base<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>>::type Base;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_CWISE_TERNARY_OP_H
|
|
||||||
@@ -1,41 +1,38 @@
|
|||||||
// 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-2014 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
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_CWISE_UNARY_OP_H
|
#ifndef EIGEN_CWISE_UNARY_OP_H
|
||||||
#define EIGEN_CWISE_UNARY_OP_H
|
#define EIGEN_CWISE_UNARY_OP_H
|
||||||
|
|
||||||
// IWYU pragma: private
|
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
template <typename UnaryOp, typename XprType>
|
|
||||||
struct traits<CwiseUnaryOp<UnaryOp, XprType> > : traits<XprType> {
|
|
||||||
typedef typename result_of<UnaryOp(const typename XprType::Scalar&)>::type Scalar;
|
|
||||||
typedef typename XprType::Nested XprTypeNested;
|
|
||||||
typedef std::remove_reference_t<XprTypeNested> XprTypeNested_;
|
|
||||||
enum { Flags = XprTypeNested_::Flags & RowMajorBit };
|
|
||||||
};
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
template <typename UnaryOp, typename XprType, typename StorageKind>
|
|
||||||
class CwiseUnaryOpImpl;
|
|
||||||
|
|
||||||
/** \class CwiseUnaryOp
|
/** \class CwiseUnaryOp
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
*
|
*
|
||||||
* \brief Generic expression where a coefficient-wise unary operator is applied to an expression
|
* \brief Generic expression where a coefficient-wise unary operator is applied to an expression
|
||||||
*
|
*
|
||||||
* \tparam UnaryOp template functor implementing the operator
|
* \param UnaryOp template functor implementing the operator
|
||||||
* \tparam XprType the type of the expression to which we are applying the unary operator
|
* \param XprType the type of the expression to which we are applying the unary operator
|
||||||
*
|
*
|
||||||
* This class represents an expression where a unary operator is applied to an expression.
|
* This class represents an expression where a unary operator is applied to an expression.
|
||||||
* It is the return type of all operations taking exactly 1 input expression, regardless of the
|
* It is the return type of all operations taking exactly 1 input expression, regardless of the
|
||||||
@@ -48,48 +45,93 @@ class CwiseUnaryOpImpl;
|
|||||||
*
|
*
|
||||||
* \sa MatrixBase::unaryExpr(const CustomUnaryOp &) const, class CwiseBinaryOp, class CwiseNullaryOp
|
* \sa MatrixBase::unaryExpr(const CustomUnaryOp &) const, class CwiseBinaryOp, class CwiseNullaryOp
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
template<typename UnaryOp, typename XprType>
|
template<typename UnaryOp, typename XprType>
|
||||||
class CwiseUnaryOp : public CwiseUnaryOpImpl<UnaryOp, XprType, typename internal::traits<XprType>::StorageKind>,
|
struct traits<CwiseUnaryOp<UnaryOp, XprType> >
|
||||||
internal::no_assignment_operator {
|
: traits<XprType>
|
||||||
|
{
|
||||||
|
typedef typename result_of<
|
||||||
|
UnaryOp(typename XprType::Scalar)
|
||||||
|
>::type Scalar;
|
||||||
|
typedef typename XprType::Nested XprTypeNested;
|
||||||
|
typedef typename remove_reference<XprTypeNested>::type _XprTypeNested;
|
||||||
|
enum {
|
||||||
|
Flags = _XprTypeNested::Flags & (
|
||||||
|
HereditaryBits | LinearAccessBit | AlignedBit
|
||||||
|
| (functor_traits<UnaryOp>::PacketAccess ? PacketAccessBit : 0)),
|
||||||
|
CoeffReadCost = _XprTypeNested::CoeffReadCost + functor_traits<UnaryOp>::Cost
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename UnaryOp, typename XprType, typename StorageKind>
|
||||||
|
class CwiseUnaryOpImpl;
|
||||||
|
|
||||||
|
template<typename UnaryOp, typename XprType>
|
||||||
|
class CwiseUnaryOp : internal::no_assignment_operator,
|
||||||
|
public CwiseUnaryOpImpl<UnaryOp, XprType, typename internal::traits<XprType>::StorageKind>
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef typename CwiseUnaryOpImpl<UnaryOp, XprType,typename internal::traits<XprType>::StorageKind>::Base Base;
|
typedef typename CwiseUnaryOpImpl<UnaryOp, XprType,typename internal::traits<XprType>::StorageKind>::Base Base;
|
||||||
EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryOp)
|
EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryOp)
|
||||||
typedef typename internal::ref_selector<XprType>::type XprTypeNested;
|
|
||||||
typedef internal::remove_all_t<XprType> NestedExpression;
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE explicit CwiseUnaryOp(const XprType& xpr,
|
inline CwiseUnaryOp(const XprType& xpr, const UnaryOp& func = UnaryOp())
|
||||||
const UnaryOp& func = UnaryOp())
|
|
||||||
: m_xpr(xpr), m_functor(func) {}
|
: m_xpr(xpr), m_functor(func) {}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index rows() const noexcept { return m_xpr.rows(); }
|
EIGEN_STRONG_INLINE Index rows() const { return m_xpr.rows(); }
|
||||||
EIGEN_DEVICE_FUNC constexpr Index cols() const noexcept { return m_xpr.cols(); }
|
EIGEN_STRONG_INLINE Index cols() const { return m_xpr.cols(); }
|
||||||
|
|
||||||
/** \returns the functor representing the unary operation */
|
/** \returns the functor representing the unary operation */
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE const UnaryOp& functor() const { return m_functor; }
|
const UnaryOp& functor() const { return m_functor; }
|
||||||
|
|
||||||
/** \returns the nested expression */
|
/** \returns the nested expression */
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE const internal::remove_all_t<XprTypeNested>& nestedExpression()
|
const typename internal::remove_all<typename XprType::Nested>::type&
|
||||||
const {
|
nestedExpression() const { return m_xpr; }
|
||||||
return m_xpr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \returns the nested expression */
|
/** \returns the nested expression */
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE internal::remove_all_t<XprTypeNested>& nestedExpression() {
|
typename internal::remove_all<typename XprType::Nested>::type&
|
||||||
return m_xpr;
|
nestedExpression() { return m_xpr.const_cast_derived(); }
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
XprTypeNested m_xpr;
|
const typename XprType::Nested m_xpr;
|
||||||
const UnaryOp m_functor;
|
const UnaryOp m_functor;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generic API dispatcher
|
// This is the generic implementation for dense storage.
|
||||||
template <typename UnaryOp, typename XprType, typename StorageKind>
|
// It can be used for any expression types implementing the dense concept.
|
||||||
class CwiseUnaryOpImpl : public internal::generic_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type {
|
template<typename UnaryOp, typename XprType>
|
||||||
|
class CwiseUnaryOpImpl<UnaryOp,XprType,Dense>
|
||||||
|
: public internal::dense_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename internal::generic_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type Base;
|
|
||||||
|
typedef CwiseUnaryOp<UnaryOp, XprType> Derived;
|
||||||
|
typedef typename internal::dense_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type Base;
|
||||||
|
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
|
||||||
|
|
||||||
|
EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const
|
||||||
|
{
|
||||||
|
return derived().functor()(derived().nestedExpression().coeff(row, col));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
|
||||||
|
{
|
||||||
|
return derived().functor().packetOp(derived().nestedExpression().template packet<LoadMode>(row, col));
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
|
||||||
|
{
|
||||||
|
return derived().functor()(derived().nestedExpression().coeff(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
|
||||||
|
{
|
||||||
|
return derived().functor().packetOp(derived().nestedExpression().template packet<LoadMode>(index));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_CWISE_UNARY_OP_H
|
#endif // EIGEN_CWISE_UNARY_OP_H
|
||||||
|
|||||||
@@ -3,167 +3,146 @@
|
|||||||
//
|
//
|
||||||
// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
|
// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_CWISE_UNARY_VIEW_H
|
#ifndef EIGEN_CWISE_UNARY_VIEW_H
|
||||||
#define EIGEN_CWISE_UNARY_VIEW_H
|
#define EIGEN_CWISE_UNARY_VIEW_H
|
||||||
|
|
||||||
// IWYU pragma: private
|
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
template <typename ViewOp, typename MatrixType, typename StrideType>
|
|
||||||
struct traits<CwiseUnaryView<ViewOp, MatrixType, StrideType> > : traits<MatrixType> {
|
|
||||||
typedef typename result_of<ViewOp(typename traits<MatrixType>::Scalar&)>::type1 ScalarRef;
|
|
||||||
static_assert(std::is_reference<ScalarRef>::value, "Views must return a reference type.");
|
|
||||||
typedef remove_all_t<ScalarRef> Scalar;
|
|
||||||
typedef typename MatrixType::Nested MatrixTypeNested;
|
|
||||||
typedef remove_all_t<MatrixTypeNested> MatrixTypeNested_;
|
|
||||||
enum {
|
|
||||||
FlagsLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
|
|
||||||
Flags =
|
|
||||||
traits<MatrixTypeNested_>::Flags &
|
|
||||||
(RowMajorBit | FlagsLvalueBit | DirectAccessBit), // FIXME DirectAccessBit should not be handled by expressions
|
|
||||||
MatrixTypeInnerStride = inner_stride_at_compile_time<MatrixType>::ret,
|
|
||||||
// need to cast the sizeof's from size_t to int explicitly, otherwise:
|
|
||||||
// "error: no integral type can represent all of the enumerator values
|
|
||||||
InnerStrideAtCompileTime =
|
|
||||||
StrideType::InnerStrideAtCompileTime == 0
|
|
||||||
? (MatrixTypeInnerStride == Dynamic
|
|
||||||
? int(Dynamic)
|
|
||||||
: int(MatrixTypeInnerStride) * int(sizeof(typename traits<MatrixType>::Scalar) / sizeof(Scalar)))
|
|
||||||
: int(StrideType::InnerStrideAtCompileTime),
|
|
||||||
|
|
||||||
OuterStrideAtCompileTime = StrideType::OuterStrideAtCompileTime == 0
|
|
||||||
? (outer_stride_at_compile_time<MatrixType>::ret == Dynamic
|
|
||||||
? int(Dynamic)
|
|
||||||
: outer_stride_at_compile_time<MatrixType>::ret *
|
|
||||||
int(sizeof(typename traits<MatrixType>::Scalar) / sizeof(Scalar)))
|
|
||||||
: int(StrideType::OuterStrideAtCompileTime)
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Generic API dispatcher
|
|
||||||
template <typename ViewOp, typename XprType, typename StrideType, typename StorageKind,
|
|
||||||
bool Mutable = !std::is_const<XprType>::value>
|
|
||||||
class CwiseUnaryViewImpl : public generic_xpr_base<CwiseUnaryView<ViewOp, XprType, StrideType> >::type {
|
|
||||||
public:
|
|
||||||
typedef typename generic_xpr_base<CwiseUnaryView<ViewOp, XprType, StrideType> >::type Base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ViewOp, typename MatrixType, typename StrideType>
|
|
||||||
class CwiseUnaryViewImpl<ViewOp, MatrixType, StrideType, Dense, false>
|
|
||||||
: public dense_xpr_base<CwiseUnaryView<ViewOp, MatrixType, StrideType> >::type {
|
|
||||||
public:
|
|
||||||
typedef CwiseUnaryView<ViewOp, MatrixType, StrideType> Derived;
|
|
||||||
typedef typename dense_xpr_base<CwiseUnaryView<ViewOp, MatrixType, StrideType> >::type Base;
|
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
|
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryViewImpl)
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline const Scalar* data() const { return &(this->coeffRef(0)); }
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index innerStride() const {
|
|
||||||
return StrideType::InnerStrideAtCompileTime != 0 ? int(StrideType::InnerStrideAtCompileTime)
|
|
||||||
: derived().nestedExpression().innerStride() *
|
|
||||||
sizeof(typename traits<MatrixType>::Scalar) / sizeof(Scalar);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index outerStride() const {
|
|
||||||
return StrideType::OuterStrideAtCompileTime != 0 ? int(StrideType::OuterStrideAtCompileTime)
|
|
||||||
: derived().nestedExpression().outerStride() *
|
|
||||||
sizeof(typename traits<MatrixType>::Scalar) / sizeof(Scalar);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(CwiseUnaryViewImpl)
|
|
||||||
|
|
||||||
// Allow const access to coeffRef for the case of direct access being enabled.
|
|
||||||
EIGEN_DEVICE_FUNC inline const Scalar& coeffRef(Index index) const {
|
|
||||||
return internal::evaluator<Derived>(derived()).coeffRef(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline const Scalar& coeffRef(Index row, Index col) const {
|
|
||||||
return internal::evaluator<Derived>(derived()).coeffRef(row, col);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ViewOp, typename MatrixType, typename StrideType>
|
|
||||||
class CwiseUnaryViewImpl<ViewOp, MatrixType, StrideType, Dense, true>
|
|
||||||
: public CwiseUnaryViewImpl<ViewOp, MatrixType, StrideType, Dense, false> {
|
|
||||||
public:
|
|
||||||
typedef CwiseUnaryViewImpl<ViewOp, MatrixType, StrideType, Dense, false> Base;
|
|
||||||
typedef CwiseUnaryView<ViewOp, MatrixType, StrideType> Derived;
|
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
|
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryViewImpl)
|
|
||||||
|
|
||||||
using Base::data;
|
|
||||||
EIGEN_DEVICE_FUNC inline Scalar* data() { return &(this->coeffRef(0)); }
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col) {
|
|
||||||
return internal::evaluator<Derived>(derived()).coeffRef(row, col);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) {
|
|
||||||
return internal::evaluator<Derived>(derived()).coeffRef(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(CwiseUnaryViewImpl)
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
/** \class CwiseUnaryView
|
/** \class CwiseUnaryView
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
*
|
*
|
||||||
* \brief Generic lvalue expression of a coefficient-wise unary operator of a matrix or a vector
|
* \brief Generic lvalue expression of a coefficient-wise unary operator of a matrix or a vector
|
||||||
*
|
*
|
||||||
* \tparam ViewOp template functor implementing the view
|
* \param ViewOp template functor implementing the view
|
||||||
* \tparam MatrixType the type of the matrix we are applying the unary operator
|
* \param MatrixType the type of the matrix we are applying the unary operator
|
||||||
*
|
*
|
||||||
* This class represents a lvalue expression of a generic unary view operator of a matrix or a vector.
|
* This class represents a lvalue expression of a generic unary view operator of a matrix or a vector.
|
||||||
* It is the return type of real() and imag(), and most of the time this is the only way it is used.
|
* It is the return type of real() and imag(), and most of the time this is the only way it is used.
|
||||||
*
|
*
|
||||||
* \sa MatrixBase::unaryViewExpr(const CustomUnaryOp &) const, class CwiseUnaryOp
|
* \sa MatrixBase::unaryViewExpr(const CustomUnaryOp &) const, class CwiseUnaryOp
|
||||||
*/
|
*/
|
||||||
template <typename ViewOp, typename MatrixType, typename StrideType>
|
|
||||||
class CwiseUnaryView : public internal::CwiseUnaryViewImpl<ViewOp, MatrixType, StrideType,
|
|
||||||
typename internal::traits<MatrixType>::StorageKind> {
|
|
||||||
public:
|
|
||||||
typedef typename internal::CwiseUnaryViewImpl<ViewOp, MatrixType, StrideType,
|
|
||||||
typename internal::traits<MatrixType>::StorageKind>::Base Base;
|
|
||||||
EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryView)
|
|
||||||
typedef typename internal::ref_selector<MatrixType>::non_const_type MatrixTypeNested;
|
|
||||||
typedef internal::remove_all_t<MatrixType> NestedExpression;
|
|
||||||
|
|
||||||
explicit EIGEN_DEVICE_FUNC constexpr inline CwiseUnaryView(MatrixType& mat, const ViewOp& func = ViewOp())
|
namespace internal {
|
||||||
|
template<typename ViewOp, typename MatrixType>
|
||||||
|
struct traits<CwiseUnaryView<ViewOp, MatrixType> >
|
||||||
|
: traits<MatrixType>
|
||||||
|
{
|
||||||
|
typedef typename result_of<
|
||||||
|
ViewOp(typename traits<MatrixType>::Scalar)
|
||||||
|
>::type Scalar;
|
||||||
|
typedef typename MatrixType::Nested MatrixTypeNested;
|
||||||
|
typedef typename remove_all<MatrixTypeNested>::type _MatrixTypeNested;
|
||||||
|
enum {
|
||||||
|
Flags = (traits<_MatrixTypeNested>::Flags & (HereditaryBits | LvalueBit | LinearAccessBit | DirectAccessBit)),
|
||||||
|
CoeffReadCost = traits<_MatrixTypeNested>::CoeffReadCost + functor_traits<ViewOp>::Cost,
|
||||||
|
MatrixTypeInnerStride = inner_stride_at_compile_time<MatrixType>::ret,
|
||||||
|
// need to cast the sizeof's from size_t to int explicitly, otherwise:
|
||||||
|
// "error: no integral type can represent all of the enumerator values
|
||||||
|
InnerStrideAtCompileTime = MatrixTypeInnerStride == Dynamic
|
||||||
|
? int(Dynamic)
|
||||||
|
: int(MatrixTypeInnerStride)
|
||||||
|
* int(sizeof(typename traits<MatrixType>::Scalar) / sizeof(Scalar)),
|
||||||
|
OuterStrideAtCompileTime = outer_stride_at_compile_time<MatrixType>::ret
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ViewOp, typename MatrixType, typename StorageKind>
|
||||||
|
class CwiseUnaryViewImpl;
|
||||||
|
|
||||||
|
template<typename ViewOp, typename MatrixType>
|
||||||
|
class CwiseUnaryView : internal::no_assignment_operator,
|
||||||
|
public CwiseUnaryViewImpl<ViewOp, MatrixType, typename internal::traits<MatrixType>::StorageKind>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef typename CwiseUnaryViewImpl<ViewOp, MatrixType,typename internal::traits<MatrixType>::StorageKind>::Base Base;
|
||||||
|
EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryView)
|
||||||
|
|
||||||
|
inline CwiseUnaryView(const MatrixType& mat, const ViewOp& func = ViewOp())
|
||||||
: m_matrix(mat), m_functor(func) {}
|
: m_matrix(mat), m_functor(func) {}
|
||||||
|
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryView)
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryView)
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index rows() const noexcept { return m_matrix.rows(); }
|
EIGEN_STRONG_INLINE Index rows() const { return m_matrix.rows(); }
|
||||||
EIGEN_DEVICE_FUNC constexpr Index cols() const noexcept { return m_matrix.cols(); }
|
EIGEN_STRONG_INLINE Index cols() const { return m_matrix.cols(); }
|
||||||
|
|
||||||
/** \returns the functor representing unary operation */
|
/** \returns the functor representing unary operation */
|
||||||
EIGEN_DEVICE_FUNC constexpr 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 constexpr const internal::remove_all_t<MatrixTypeNested>& nestedExpression() const {
|
const typename internal::remove_all<typename MatrixType::Nested>::type&
|
||||||
return m_matrix;
|
nestedExpression() const { return m_matrix; }
|
||||||
}
|
|
||||||
|
|
||||||
/** \returns the nested expression */
|
/** \returns the nested expression */
|
||||||
EIGEN_DEVICE_FUNC constexpr std::remove_reference_t<MatrixTypeNested>& nestedExpression() { return m_matrix; }
|
typename internal::remove_all<typename MatrixType::Nested>::type&
|
||||||
|
nestedExpression() { return m_matrix.const_cast_derived(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MatrixTypeNested m_matrix;
|
// FIXME changed from MatrixType::Nested because of a weird compilation error with sun CC
|
||||||
|
const typename internal::nested<MatrixType>::type m_matrix;
|
||||||
ViewOp m_functor;
|
ViewOp m_functor;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Eigen
|
template<typename ViewOp, typename MatrixType>
|
||||||
|
class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense>
|
||||||
|
: public internal::dense_xpr_base< CwiseUnaryView<ViewOp, MatrixType> >::type
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef CwiseUnaryView<ViewOp, MatrixType> Derived;
|
||||||
|
typedef typename internal::dense_xpr_base< CwiseUnaryView<ViewOp, MatrixType> >::type Base;
|
||||||
|
|
||||||
|
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
|
||||||
|
|
||||||
|
inline Index innerStride() const
|
||||||
|
{
|
||||||
|
return derived().nestedExpression().innerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Index outerStride() const
|
||||||
|
{
|
||||||
|
return derived().nestedExpression().outerStride();
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const
|
||||||
|
{
|
||||||
|
return derived().functor()(derived().nestedExpression().coeff(row, col));
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const
|
||||||
|
{
|
||||||
|
return derived().functor()(derived().nestedExpression().coeff(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
|
||||||
|
{
|
||||||
|
return derived().functor()(const_cast_derived().nestedExpression().coeffRef(row, col));
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
|
||||||
|
{
|
||||||
|
return derived().functor()(const_cast_derived().nestedExpression().coeffRef(index));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // EIGEN_CWISE_UNARY_VIEW_H
|
#endif // EIGEN_CWISE_UNARY_VIEW_H
|
||||||
|
|||||||
@@ -4,21 +4,28 @@
|
|||||||
// Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
|
// Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||||
// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
|
// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_DENSEBASE_H
|
#ifndef EIGEN_DENSEBASE_H
|
||||||
#define EIGEN_DENSEBASE_H
|
#define EIGEN_DENSEBASE_H
|
||||||
|
|
||||||
// IWYU pragma: private
|
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
// The index type defined by EIGEN_DEFAULT_DENSE_INDEX_TYPE must be a signed type.
|
|
||||||
EIGEN_STATIC_ASSERT(NumTraits<DenseIndex>::IsSigned, THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE)
|
|
||||||
|
|
||||||
/** \class DenseBase
|
/** \class DenseBase
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
*
|
*
|
||||||
@@ -30,65 +37,67 @@ EIGEN_STATIC_ASSERT(NumTraits<DenseIndex>::IsSigned, THE_INDEX_TYPE_MUST_BE_A_SI
|
|||||||
* \tparam Derived is the derived type, e.g., a matrix type or an expression.
|
* \tparam Derived is the derived type, e.g., a matrix type or an expression.
|
||||||
*
|
*
|
||||||
* This class can be extended with the help of the plugin mechanism described on the page
|
* This class can be extended with the help of the plugin mechanism described on the page
|
||||||
* \ref TopicCustomizing_Plugins by defining the preprocessor symbol \c EIGEN_DENSEBASE_PLUGIN.
|
* \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_DENSEBASE_PLUGIN.
|
||||||
*
|
*
|
||||||
* \sa \blank \ref TopicClassHierarchy
|
* \sa \ref TopicClassHierarchy
|
||||||
*/
|
*/
|
||||||
template <typename Derived>
|
template<typename Derived> class DenseBase
|
||||||
class DenseBase
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
: public DenseCoeffsBase<Derived, internal::accessors_level<Derived>::value>
|
: public internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar,
|
||||||
|
typename NumTraits<typename internal::traits<Derived>::Scalar>::Real>
|
||||||
#else
|
#else
|
||||||
: public DenseCoeffsBase<Derived, DirectWriteAccessors>
|
: public DenseCoeffsBase<Derived>
|
||||||
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** Inner iterator type to iterate over the coefficients of a row or column.
|
using internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar,
|
||||||
* \sa class InnerIterator
|
typename NumTraits<typename internal::traits<Derived>::Scalar>::Real>::operator*;
|
||||||
*/
|
|
||||||
typedef Eigen::InnerIterator<Derived> InnerIterator;
|
class InnerIterator;
|
||||||
|
|
||||||
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
||||||
|
|
||||||
/**
|
/** \brief The type of indices
|
||||||
* \brief The type used to store indices
|
* \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE.
|
||||||
* \details This typedef is relevant for types that store multiple indices such as
|
* \sa \ref TopicPreprocessorDirectives.
|
||||||
* PermutationMatrix or Transpositions, otherwise it defaults to Eigen::Index
|
|
||||||
* \sa \blank \ref TopicPreprocessorDirectives, Eigen::Index, SparseMatrixBase.
|
|
||||||
*/
|
*/
|
||||||
typedef typename internal::traits<Derived>::StorageIndex StorageIndex;
|
typedef typename internal::traits<Derived>::Index Index;
|
||||||
|
|
||||||
/** The numeric type of the expression' coefficients, e.g. float, double, int or std::complex<float>, etc. */
|
|
||||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||||
|
typedef typename internal::packet_traits<Scalar>::type PacketScalar;
|
||||||
/** The numeric type of the expression' coefficients, e.g. float, double, int or std::complex<float>, etc.
|
|
||||||
*
|
|
||||||
* It is an alias for the Scalar type */
|
|
||||||
typedef Scalar value_type;
|
|
||||||
|
|
||||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||||
typedef DenseCoeffsBase<Derived, internal::accessors_level<Derived>::value> Base;
|
|
||||||
|
|
||||||
|
typedef DenseCoeffsBase<Derived> Base;
|
||||||
|
using Base::derived;
|
||||||
|
using Base::const_cast_derived;
|
||||||
|
using Base::rows;
|
||||||
|
using Base::cols;
|
||||||
|
using Base::size;
|
||||||
|
using Base::rowIndexByOuterInner;
|
||||||
|
using Base::colIndexByOuterInner;
|
||||||
using Base::coeff;
|
using Base::coeff;
|
||||||
using Base::coeffByOuterInner;
|
using Base::coeffByOuterInner;
|
||||||
using Base::colIndexByOuterInner;
|
using Base::packet;
|
||||||
using Base::cols;
|
using Base::packetByOuterInner;
|
||||||
using Base::const_cast_derived;
|
using Base::writePacket;
|
||||||
using Base::derived;
|
using Base::writePacketByOuterInner;
|
||||||
using Base::rowIndexByOuterInner;
|
using Base::coeffRef;
|
||||||
using Base::rows;
|
using Base::coeffRefByOuterInner;
|
||||||
using Base::size;
|
using Base::copyCoeff;
|
||||||
|
using Base::copyCoeffByOuterInner;
|
||||||
|
using Base::copyPacket;
|
||||||
|
using Base::copyPacketByOuterInner;
|
||||||
using Base::operator();
|
using Base::operator();
|
||||||
using Base::operator[];
|
using Base::operator[];
|
||||||
using Base::colStride;
|
|
||||||
using Base::innerStride;
|
|
||||||
using Base::outerStride;
|
|
||||||
using Base::rowStride;
|
|
||||||
using Base::stride;
|
|
||||||
using Base::w;
|
|
||||||
using Base::x;
|
using Base::x;
|
||||||
using Base::y;
|
using Base::y;
|
||||||
using Base::z;
|
using Base::z;
|
||||||
|
using Base::w;
|
||||||
|
using Base::stride;
|
||||||
|
using Base::innerStride;
|
||||||
|
using Base::outerStride;
|
||||||
|
using Base::rowStride;
|
||||||
|
using Base::colStride;
|
||||||
typedef typename Base::CoeffReturnType CoeffReturnType;
|
typedef typename Base::CoeffReturnType CoeffReturnType;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -105,7 +114,9 @@ class DenseBase
|
|||||||
* it is set to the \a Dynamic constant.
|
* it is set to the \a Dynamic constant.
|
||||||
* \sa MatrixBase::rows(), MatrixBase::cols(), RowsAtCompileTime, SizeAtCompileTime */
|
* \sa MatrixBase::rows(), MatrixBase::cols(), RowsAtCompileTime, SizeAtCompileTime */
|
||||||
|
|
||||||
SizeAtCompileTime = (internal::size_of_xpr_at_compile_time<Derived>::ret),
|
|
||||||
|
SizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::RowsAtCompileTime,
|
||||||
|
internal::traits<Derived>::ColsAtCompileTime>::ret),
|
||||||
/**< This is equal to the number of coefficients, i.e. the number of
|
/**< This is equal to the number of coefficients, i.e. the number of
|
||||||
* rows times the number of columns, or to \a Dynamic if this is not
|
* rows times the number of columns, or to \a Dynamic if this is not
|
||||||
* known at compile-time. \sa RowsAtCompileTime, ColsAtCompileTime */
|
* known at compile-time. \sa RowsAtCompileTime, ColsAtCompileTime */
|
||||||
@@ -132,8 +143,8 @@ class DenseBase
|
|||||||
* \sa ColsAtCompileTime, MaxRowsAtCompileTime, MaxSizeAtCompileTime
|
* \sa ColsAtCompileTime, MaxRowsAtCompileTime, MaxSizeAtCompileTime
|
||||||
*/
|
*/
|
||||||
|
|
||||||
MaxSizeAtCompileTime = internal::size_at_compile_time(internal::traits<Derived>::MaxRowsAtCompileTime,
|
MaxSizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::MaxRowsAtCompileTime,
|
||||||
internal::traits<Derived>::MaxColsAtCompileTime),
|
internal::traits<Derived>::MaxColsAtCompileTime>::ret),
|
||||||
/**< This value is equal to the maximum possible number of coefficients that this expression
|
/**< This value is equal to the maximum possible number of coefficients that this expression
|
||||||
* might have. If this expression might have an arbitrarily high number of coefficients,
|
* might have. If this expression might have an arbitrarily high number of coefficients,
|
||||||
* this value is set to \a Dynamic.
|
* this value is set to \a Dynamic.
|
||||||
@@ -144,20 +155,13 @@ class DenseBase
|
|||||||
* \sa SizeAtCompileTime, MaxRowsAtCompileTime, MaxColsAtCompileTime
|
* \sa SizeAtCompileTime, MaxRowsAtCompileTime, MaxColsAtCompileTime
|
||||||
*/
|
*/
|
||||||
|
|
||||||
IsVectorAtCompileTime =
|
IsVectorAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime == 1
|
||||||
internal::traits<Derived>::RowsAtCompileTime == 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".
|
||||||
@@ -166,50 +170,36 @@ class DenseBase
|
|||||||
IsRowMajor = int(Flags) & RowMajorBit, /**< True if this expression has row-major storage order. */
|
IsRowMajor = int(Flags) & RowMajorBit, /**< True if this expression has row-major storage order. */
|
||||||
|
|
||||||
InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime)
|
InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime)
|
||||||
: int(IsRowMajor) ? int(ColsAtCompileTime)
|
: int(IsRowMajor) ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
|
||||||
: int(RowsAtCompileTime),
|
|
||||||
|
CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
|
||||||
|
/**< This is a rough measure of how expensive it is to read one coefficient from
|
||||||
|
* this expression.
|
||||||
|
*/
|
||||||
|
|
||||||
InnerStrideAtCompileTime = internal::inner_stride_at_compile_time<Derived>::ret,
|
InnerStrideAtCompileTime = internal::inner_stride_at_compile_time<Derived>::ret,
|
||||||
OuterStrideAtCompileTime = internal::outer_stride_at_compile_time<Derived>::ret
|
OuterStrideAtCompileTime = internal::outer_stride_at_compile_time<Derived>::ret
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef typename internal::find_best_packet<Scalar, SizeAtCompileTime>::type PacketScalar;
|
enum { ThisConstantIsPrivateInPlainObjectBase };
|
||||||
|
|
||||||
enum { IsPlainObjectBase = 0 };
|
/** \returns the number of nonzero coefficients which is in practice the number
|
||||||
|
* of stored coefficients. */
|
||||||
/** The plain matrix type corresponding to this expression.
|
inline Index nonZeros() const { return size(); }
|
||||||
* \sa PlainObject */
|
/** \returns true if either the number of rows or the number of columns is equal to 1.
|
||||||
typedef Matrix<typename internal::traits<Derived>::Scalar, internal::traits<Derived>::RowsAtCompileTime,
|
* In other words, this function returns
|
||||||
internal::traits<Derived>::ColsAtCompileTime,
|
* \code rows()==1 || cols()==1 \endcode
|
||||||
AutoAlign | (internal::traits<Derived>::Flags & RowMajorBit ? RowMajor : ColMajor),
|
* \sa rows(), cols(), IsVectorAtCompileTime. */
|
||||||
internal::traits<Derived>::MaxRowsAtCompileTime, internal::traits<Derived>::MaxColsAtCompileTime>
|
|
||||||
PlainMatrix;
|
|
||||||
|
|
||||||
/** The plain array type corresponding to this expression.
|
|
||||||
* \sa PlainObject */
|
|
||||||
typedef Array<typename internal::traits<Derived>::Scalar, internal::traits<Derived>::RowsAtCompileTime,
|
|
||||||
internal::traits<Derived>::ColsAtCompileTime,
|
|
||||||
AutoAlign | (internal::traits<Derived>::Flags & RowMajorBit ? RowMajor : ColMajor),
|
|
||||||
internal::traits<Derived>::MaxRowsAtCompileTime, internal::traits<Derived>::MaxColsAtCompileTime>
|
|
||||||
PlainArray;
|
|
||||||
|
|
||||||
/** \brief The plain matrix or array type corresponding to this expression.
|
|
||||||
*
|
|
||||||
* This is not necessarily exactly the return type of eval(). In the case of plain matrices,
|
|
||||||
* the return type of eval() is a const reference to a matrix, not a matrix! It is however guaranteed
|
|
||||||
* that the return type of eval() is either PlainObject or const PlainObject&.
|
|
||||||
*/
|
|
||||||
typedef std::conditional_t<internal::is_same<typename internal::traits<Derived>::XprKind, MatrixXpr>::value,
|
|
||||||
PlainMatrix, PlainArray>
|
|
||||||
PlainObject;
|
|
||||||
|
|
||||||
/** \returns the outer size.
|
/** \returns the outer size.
|
||||||
*
|
*
|
||||||
* \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 constexpr Index outerSize() const {
|
Index outerSize() const
|
||||||
return IsVectorAtCompileTime ? 1 : int(IsRowMajor) ? this->rows() : this->cols();
|
{
|
||||||
|
return IsVectorAtCompileTime ? 1
|
||||||
|
: int(IsRowMajor) ? this->rows() : this->cols();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the inner size.
|
/** \returns the inner size.
|
||||||
@@ -217,173 +207,182 @@ 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 constexpr Index innerSize() const {
|
Index innerSize() const
|
||||||
return IsVectorAtCompileTime ? this->size() : int(IsRowMajor) ? this->cols() : this->rows();
|
{
|
||||||
|
return IsVectorAtCompileTime ? this->size()
|
||||||
|
: int(IsRowMajor) ? this->cols() : this->rows();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Only plain matrices/arrays, not expressions, may be resized; therefore the only useful resize methods are
|
/** Only plain matrices/arrays, not expressions, may be resized; therefore the only useful resize methods are
|
||||||
* Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and
|
* Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and does
|
||||||
* does nothing else.
|
* nothing else.
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC void resize(Index newSize) {
|
void resize(Index size)
|
||||||
EIGEN_ONLY_USED_FOR_DEBUG(newSize);
|
{
|
||||||
eigen_assert(newSize == this->size() && "DenseBase::resize() does not actually allow to resize.");
|
EIGEN_ONLY_USED_FOR_DEBUG(size);
|
||||||
|
eigen_assert(size == this->size()
|
||||||
|
&& "DenseBase::resize() does not actually allow to resize.");
|
||||||
}
|
}
|
||||||
/** Only plain matrices/arrays, not expressions, may be resized; therefore the only useful resize methods are
|
/** Only plain matrices/arrays, not expressions, may be resized; therefore the only useful resize methods are
|
||||||
* Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and
|
* Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and does
|
||||||
* does nothing else.
|
* nothing else.
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC void resize(Index rows, Index cols) {
|
void resize(Index rows, Index cols)
|
||||||
|
{
|
||||||
EIGEN_ONLY_USED_FOR_DEBUG(rows);
|
EIGEN_ONLY_USED_FOR_DEBUG(rows);
|
||||||
EIGEN_ONLY_USED_FOR_DEBUG(cols);
|
EIGEN_ONLY_USED_FOR_DEBUG(cols);
|
||||||
eigen_assert(rows == this->rows() && cols == this->cols() &&
|
eigen_assert(rows == this->rows() && cols == this->cols()
|
||||||
"DenseBase::resize() does not actually allow to resize.");
|
&& "DenseBase::resize() does not actually allow to resize.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
|
||||||
/** \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>,Derived> ConstantReturnType;
|
||||||
/** \internal Represents a matrix with all coefficients equal to zero*/
|
/** \internal Represents a vector with linearly spaced coefficients that allows sequential access only. */
|
||||||
typedef CwiseNullaryOp<internal::scalar_zero_op<Scalar>, PlainObject> ZeroReturnType;
|
typedef CwiseNullaryOp<internal::linspaced_op<Scalar,false>,Derived> SequentialLinSpacedReturnType;
|
||||||
/** \internal \deprecated Represents a vector with linearly spaced coefficients that allows sequential access only. */
|
|
||||||
EIGEN_DEPRECATED typedef CwiseNullaryOp<internal::linspaced_op<Scalar>, 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,true>,Derived> RandomAccessLinSpacedReturnType;
|
||||||
/** \internal Represents a vector with equally spaced coefficients that allows random access. */
|
|
||||||
typedef CwiseNullaryOp<internal::equalspaced_op<Scalar>, PlainObject> RandomAccessEqualSpacedReturnType;
|
|
||||||
/** \internal the return type of MatrixBase::eigenvalues() */
|
/** \internal the return type of MatrixBase::eigenvalues() */
|
||||||
typedef Matrix<typename NumTraits<typename internal::traits<Derived>::Scalar>::Real,
|
typedef Matrix<typename NumTraits<typename internal::traits<Derived>::Scalar>::Real, internal::traits<Derived>::ColsAtCompileTime, 1> EigenvaluesReturnType;
|
||||||
internal::traits<Derived>::ColsAtCompileTime, 1>
|
|
||||||
EigenvaluesReturnType;
|
|
||||||
|
|
||||||
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
|
||||||
/** Copies \a other into *this. \returns a reference to *this. */
|
/** Copies \a other into *this. \returns a reference to *this. */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Derived& operator=(const DenseBase<OtherDerived>& other);
|
Derived& operator=(const DenseBase<OtherDerived>& other);
|
||||||
|
|
||||||
/** Special case of the template operator=, in order to prevent the compiler
|
/** Special case of the template operator=, in order to prevent the compiler
|
||||||
* from generating a default operator= (issue hit with g++ 4.1)
|
* from generating a default operator= (issue hit with g++ 4.1)
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Derived& operator=(const DenseBase& other);
|
Derived& operator=(const DenseBase& other);
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC constexpr Derived& operator=(const EigenBase<OtherDerived>& other);
|
Derived& operator=(const EigenBase<OtherDerived> &other);
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC constexpr Derived& operator+=(const EigenBase<OtherDerived>& other);
|
Derived& operator+=(const EigenBase<OtherDerived> &other);
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC constexpr Derived& operator-=(const EigenBase<OtherDerived>& other);
|
Derived& operator-=(const EigenBase<OtherDerived> &other);
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC Derived& operator=(const ReturnByValue<OtherDerived>& func);
|
Derived& operator=(const ReturnByValue<OtherDerived>& func);
|
||||||
|
|
||||||
/** \internal
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
* 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. */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
/** \deprecated */
|
Derived& lazyAssign(const DenseBase<OtherDerived>& other);
|
||||||
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC constexpr Derived& lazyAssign(const DenseBase<OtherDerived>& other);
|
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC CommaInitializer<Derived> operator<<(const Scalar& s);
|
CommaInitializer<Derived> operator<< (const Scalar& s);
|
||||||
|
|
||||||
template<unsigned int Added,unsigned int Removed>
|
template<unsigned int Added,unsigned int Removed>
|
||||||
/** \deprecated it now returns \c *this */
|
const Flagged<Derived, Added, Removed> flagged() const;
|
||||||
EIGEN_DEPRECATED const Derived& flagged() const {
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC CommaInitializer<Derived> operator<<(const DenseBase<OtherDerived>& other);
|
CommaInitializer<Derived> operator<< (const DenseBase<OtherDerived>& other);
|
||||||
|
|
||||||
typedef Transpose<Derived> TransposeReturnType;
|
Eigen::Transpose<Derived> transpose();
|
||||||
EIGEN_DEVICE_FUNC TransposeReturnType transpose();
|
typedef const Transpose<const Derived> ConstTransposeReturnType;
|
||||||
typedef Transpose<const Derived> ConstTransposeReturnType;
|
ConstTransposeReturnType transpose() const;
|
||||||
EIGEN_DEVICE_FUNC const ConstTransposeReturnType transpose() const;
|
void transposeInPlace();
|
||||||
EIGEN_DEVICE_FUNC void transposeInPlace();
|
#ifndef EIGEN_NO_DEBUG
|
||||||
|
protected:
|
||||||
|
template<typename OtherDerived>
|
||||||
|
void checkTransposeAliasing(const OtherDerived& other) const;
|
||||||
|
public:
|
||||||
|
#endif
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC static const ConstantReturnType Constant(Index rows, Index cols, const Scalar& value);
|
typedef VectorBlock<Derived> SegmentReturnType;
|
||||||
EIGEN_DEVICE_FUNC static const ConstantReturnType Constant(Index size, const Scalar& value);
|
typedef const VectorBlock<const Derived> ConstSegmentReturnType;
|
||||||
EIGEN_DEVICE_FUNC static const ConstantReturnType Constant(const Scalar& value);
|
template<int Size> struct FixedSegmentReturnType { typedef VectorBlock<Derived, Size> Type; };
|
||||||
|
template<int Size> struct ConstFixedSegmentReturnType { typedef const VectorBlock<const Derived, Size> Type; };
|
||||||
|
|
||||||
EIGEN_DEPRECATED_WITH_REASON("The method may result in accuracy loss. Use .EqualSpaced() instead.")
|
// Note: The "DenseBase::" prefixes are added to help MSVC9 to match these declarations with the later implementations.
|
||||||
EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType LinSpaced(Sequential_t, Index size, const Scalar& low,
|
SegmentReturnType segment(Index start, Index size);
|
||||||
const Scalar& high);
|
typename DenseBase::ConstSegmentReturnType segment(Index start, Index size) const;
|
||||||
EIGEN_DEPRECATED_WITH_REASON("The method may result in accuracy loss. Use .EqualSpaced() instead.")
|
|
||||||
EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType LinSpaced(Sequential_t, const Scalar& low,
|
|
||||||
const Scalar& high);
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType LinSpaced(Index size, const Scalar& low,
|
SegmentReturnType head(Index size);
|
||||||
const Scalar& high);
|
typename DenseBase::ConstSegmentReturnType head(Index size) const;
|
||||||
EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType LinSpaced(const Scalar& low, const Scalar& high);
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC static const RandomAccessEqualSpacedReturnType EqualSpaced(Index size, const Scalar& low,
|
SegmentReturnType tail(Index size);
|
||||||
const Scalar& step);
|
typename DenseBase::ConstSegmentReturnType tail(Index size) const;
|
||||||
EIGEN_DEVICE_FUNC static const RandomAccessEqualSpacedReturnType EqualSpaced(const Scalar& low, const Scalar& step);
|
|
||||||
|
template<int Size> typename FixedSegmentReturnType<Size>::Type head();
|
||||||
|
template<int Size> typename ConstFixedSegmentReturnType<Size>::Type head() const;
|
||||||
|
|
||||||
|
template<int Size> typename FixedSegmentReturnType<Size>::Type tail();
|
||||||
|
template<int Size> typename ConstFixedSegmentReturnType<Size>::Type tail() const;
|
||||||
|
|
||||||
|
template<int Size> typename FixedSegmentReturnType<Size>::Type segment(Index start);
|
||||||
|
template<int Size> typename ConstFixedSegmentReturnType<Size>::Type segment(Index start) const;
|
||||||
|
|
||||||
|
static const ConstantReturnType
|
||||||
|
Constant(Index rows, Index cols, const Scalar& value);
|
||||||
|
static const ConstantReturnType
|
||||||
|
Constant(Index size, const Scalar& value);
|
||||||
|
static const ConstantReturnType
|
||||||
|
Constant(const Scalar& value);
|
||||||
|
|
||||||
|
static const SequentialLinSpacedReturnType
|
||||||
|
LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high);
|
||||||
|
static const RandomAccessLinSpacedReturnType
|
||||||
|
LinSpaced(Index size, const Scalar& low, const Scalar& high);
|
||||||
|
static const SequentialLinSpacedReturnType
|
||||||
|
LinSpaced(Sequential_t, const Scalar& low, const Scalar& high);
|
||||||
|
static const RandomAccessLinSpacedReturnType
|
||||||
|
LinSpaced(const Scalar& low, const Scalar& high);
|
||||||
|
|
||||||
template<typename CustomNullaryOp>
|
template<typename CustomNullaryOp>
|
||||||
EIGEN_DEVICE_FUNC static const CwiseNullaryOp<CustomNullaryOp, PlainObject> NullaryExpr(Index rows, Index cols,
|
static const CwiseNullaryOp<CustomNullaryOp, Derived>
|
||||||
const CustomNullaryOp& func);
|
NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func);
|
||||||
template<typename CustomNullaryOp>
|
template<typename CustomNullaryOp>
|
||||||
EIGEN_DEVICE_FUNC static const CwiseNullaryOp<CustomNullaryOp, PlainObject> NullaryExpr(Index size,
|
static const CwiseNullaryOp<CustomNullaryOp, Derived>
|
||||||
const CustomNullaryOp& func);
|
NullaryExpr(Index size, const CustomNullaryOp& func);
|
||||||
template<typename CustomNullaryOp>
|
template<typename CustomNullaryOp>
|
||||||
EIGEN_DEVICE_FUNC static const CwiseNullaryOp<CustomNullaryOp, PlainObject> NullaryExpr(const CustomNullaryOp& func);
|
static const CwiseNullaryOp<CustomNullaryOp, Derived>
|
||||||
|
NullaryExpr(const CustomNullaryOp& func);
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC static const ZeroReturnType Zero(Index rows, Index cols);
|
static const ConstantReturnType Zero(Index rows, Index cols);
|
||||||
EIGEN_DEVICE_FUNC static const ZeroReturnType Zero(Index size);
|
static const ConstantReturnType Zero(Index size);
|
||||||
EIGEN_DEVICE_FUNC static const ZeroReturnType Zero();
|
static const ConstantReturnType Zero();
|
||||||
EIGEN_DEVICE_FUNC static const ConstantReturnType Ones(Index rows, Index cols);
|
static const ConstantReturnType Ones(Index rows, Index cols);
|
||||||
EIGEN_DEVICE_FUNC static const ConstantReturnType Ones(Index size);
|
static const ConstantReturnType Ones(Index size);
|
||||||
EIGEN_DEVICE_FUNC static const ConstantReturnType Ones();
|
static const ConstantReturnType Ones();
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC void fill(const Scalar& value);
|
void fill(const Scalar& value);
|
||||||
EIGEN_DEVICE_FUNC Derived& setConstant(const Scalar& value);
|
Derived& setConstant(const Scalar& value);
|
||||||
EIGEN_DEVICE_FUNC Derived& setLinSpaced(Index size, const Scalar& low, const Scalar& high);
|
Derived& setLinSpaced(Index size, const Scalar& low, const Scalar& high);
|
||||||
EIGEN_DEVICE_FUNC Derived& setLinSpaced(const Scalar& low, const Scalar& high);
|
Derived& setLinSpaced(const Scalar& low, const Scalar& high);
|
||||||
EIGEN_DEVICE_FUNC Derived& setEqualSpaced(Index size, const Scalar& low, const Scalar& step);
|
Derived& setZero();
|
||||||
EIGEN_DEVICE_FUNC Derived& setEqualSpaced(const Scalar& low, const Scalar& step);
|
Derived& setOnes();
|
||||||
EIGEN_DEVICE_FUNC Derived& setZero();
|
Derived& setRandom();
|
||||||
EIGEN_DEVICE_FUNC Derived& setOnes();
|
|
||||||
EIGEN_DEVICE_FUNC Derived& setRandom();
|
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC constexpr bool isApprox(const DenseBase<OtherDerived>& other,
|
bool isApprox(const DenseBase<OtherDerived>& other,
|
||||||
const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||||
EIGEN_DEVICE_FUNC constexpr bool isMuchSmallerThan(
|
bool isMuchSmallerThan(const RealScalar& other,
|
||||||
const RealScalar& other, const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC constexpr bool isMuchSmallerThan(
|
bool isMuchSmallerThan(const DenseBase<OtherDerived>& other,
|
||||||
const DenseBase<OtherDerived>& other, const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC bool isApproxToConstant(const Scalar& value,
|
bool isApproxToConstant(const Scalar& value, RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||||
const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
bool isConstant(const Scalar& value, RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||||
EIGEN_DEVICE_FUNC bool isConstant(const Scalar& value,
|
bool isZero(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||||
const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
bool isOnes(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||||
EIGEN_DEVICE_FUNC bool isZero(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
|
||||||
EIGEN_DEVICE_FUNC bool isOnes(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline bool hasNaN() const;
|
inline Derived& operator*=(const Scalar& other);
|
||||||
EIGEN_DEVICE_FUNC inline bool allFinite() const;
|
inline Derived& operator/=(const Scalar& other);
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Derived& operator*=(const Scalar& other);
|
|
||||||
template <bool Enable = internal::complex_array_access<Scalar>::value, typename = std::enable_if_t<Enable>>
|
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Derived& operator*=(const RealScalar& other);
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Derived& operator/=(const Scalar& other);
|
|
||||||
template <bool Enable = internal::complex_array_access<Scalar>::value, typename = std::enable_if_t<Enable>>
|
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Derived& operator/=(const RealScalar& other);
|
|
||||||
|
|
||||||
typedef internal::add_const_on_value_type_t<typename internal::eval<Derived>::type> EvalReturnType;
|
|
||||||
/** \returns the matrix or vector obtained by evaluating this expression.
|
/** \returns the matrix or vector obtained by evaluating this expression.
|
||||||
*
|
*
|
||||||
* Notice that in the case of a plain matrix or vector (not an expression) this function just returns
|
* 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.
|
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EvalReturnType eval() const {
|
EIGEN_STRONG_INLINE const typename internal::eval<Derived>::type eval() const
|
||||||
|
{
|
||||||
// Even though MSVC does not honor strong inlining when the return type
|
// Even though MSVC does not honor strong inlining when the return type
|
||||||
// is a dynamic matrix, we desperately need strong inlining for fixed
|
// is a dynamic matrix, we desperately need strong inlining for fixed
|
||||||
// size types on MSVC.
|
// size types on MSVC.
|
||||||
@@ -394,280 +393,151 @@ class DenseBase
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 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);
|
int = OtherDerived::ThisConstantIsPrivateInPlainObjectBase)
|
||||||
eigen_assert(rows() == other.rows() && cols() == other.cols());
|
{
|
||||||
call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
|
SwapWrapper<Derived>(derived()).lazyAssign(other.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** swaps *this with the matrix or array \a other.
|
/** swaps *this with the matrix or array \a other.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void swap(PlainObjectBase<OtherDerived>& other) {
|
void swap(PlainObjectBase<OtherDerived>& other)
|
||||||
eigen_assert(rows() == other.rows() && cols() == other.cols());
|
{
|
||||||
call_assignment(derived(), other.derived(), internal::swap_assign_op<Scalar>());
|
SwapWrapper<Derived>(derived()).lazyAssign(other.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr inline const NestByValue<Derived> nestByValue() const;
|
|
||||||
EIGEN_DEVICE_FUNC inline const ForceAlignedAccess<Derived> forceAlignedAccess() const;
|
|
||||||
EIGEN_DEVICE_FUNC inline ForceAlignedAccess<Derived> forceAlignedAccess();
|
|
||||||
template <bool Enable>
|
|
||||||
EIGEN_DEVICE_FUNC inline const std::conditional_t<Enable, ForceAlignedAccess<Derived>, Derived&>
|
|
||||||
forceAlignedAccessIf() const;
|
|
||||||
template <bool Enable>
|
|
||||||
EIGEN_DEVICE_FUNC inline std::conditional_t<Enable, ForceAlignedAccess<Derived>, Derived&> forceAlignedAccessIf();
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC Scalar sum() const;
|
inline const NestByValue<Derived> nestByValue() const;
|
||||||
EIGEN_DEVICE_FUNC Scalar mean() const;
|
inline const ForceAlignedAccess<Derived> forceAlignedAccess() const;
|
||||||
EIGEN_DEVICE_FUNC Scalar trace() const;
|
inline ForceAlignedAccess<Derived> forceAlignedAccess();
|
||||||
|
template<bool Enable> inline const typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type forceAlignedAccessIf() const;
|
||||||
|
template<bool Enable> inline typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type forceAlignedAccessIf();
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC Scalar prod() const;
|
Scalar sum() const;
|
||||||
|
Scalar mean() const;
|
||||||
|
Scalar trace() const;
|
||||||
|
|
||||||
template <int NaNPropagation>
|
Scalar prod() const;
|
||||||
EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar minCoeff() const;
|
|
||||||
template <int NaNPropagation>
|
|
||||||
EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar maxCoeff() const;
|
|
||||||
|
|
||||||
// By default, the fastest version with undefined NaN propagation semantics is
|
typename internal::traits<Derived>::Scalar minCoeff() const;
|
||||||
// used.
|
typename internal::traits<Derived>::Scalar maxCoeff() const;
|
||||||
// TODO(rmlarsen): Replace with default template argument (C++14 is now the minimum standard).
|
|
||||||
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;
|
|
||||||
template <int NaNPropagation, typename IndexType>
|
|
||||||
EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar maxCoeff(IndexType* row, IndexType* col) const;
|
|
||||||
template <int NaNPropagation, typename IndexType>
|
|
||||||
EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar minCoeff(IndexType* index) const;
|
|
||||||
template <int NaNPropagation, typename IndexType>
|
|
||||||
EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar maxCoeff(IndexType* index) const;
|
|
||||||
|
|
||||||
// TODO(rmlarsen): Replace these methods with a default template argument (C++14 is now the minimum standard).
|
|
||||||
template<typename IndexType>
|
template<typename IndexType>
|
||||||
EIGEN_DEVICE_FUNC inline typename internal::traits<Derived>::Scalar minCoeff(IndexType* row, IndexType* col) const {
|
typename internal::traits<Derived>::Scalar minCoeff(IndexType* row, IndexType* col) const;
|
||||||
return minCoeff<PropagateFast>(row, col);
|
|
||||||
}
|
|
||||||
template<typename IndexType>
|
template<typename IndexType>
|
||||||
EIGEN_DEVICE_FUNC inline typename internal::traits<Derived>::Scalar maxCoeff(IndexType* row, IndexType* col) const {
|
typename internal::traits<Derived>::Scalar maxCoeff(IndexType* row, IndexType* col) const;
|
||||||
return maxCoeff<PropagateFast>(row, col);
|
|
||||||
}
|
|
||||||
template<typename IndexType>
|
template<typename IndexType>
|
||||||
EIGEN_DEVICE_FUNC inline typename internal::traits<Derived>::Scalar minCoeff(IndexType* index) const {
|
typename internal::traits<Derived>::Scalar minCoeff(IndexType* index) const;
|
||||||
return minCoeff<PropagateFast>(index);
|
|
||||||
}
|
|
||||||
template<typename IndexType>
|
template<typename IndexType>
|
||||||
EIGEN_DEVICE_FUNC inline typename internal::traits<Derived>::Scalar maxCoeff(IndexType* index) const {
|
typename internal::traits<Derived>::Scalar maxCoeff(IndexType* index) const;
|
||||||
return maxCoeff<PropagateFast>(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename BinaryOp>
|
template<typename BinaryOp>
|
||||||
EIGEN_DEVICE_FUNC Scalar redux(const BinaryOp& func) const;
|
typename internal::result_of<BinaryOp(typename internal::traits<Derived>::Scalar)>::type
|
||||||
|
redux(const BinaryOp& func) const;
|
||||||
|
|
||||||
template<typename Visitor>
|
template<typename Visitor>
|
||||||
EIGEN_DEVICE_FUNC void visit(Visitor& func) const;
|
void visit(Visitor& func) const;
|
||||||
|
|
||||||
/** \returns a WithFormat proxy object allowing to print a matrix the with given
|
inline const WithFormat<Derived> format(const IOFormat& fmt) const;
|
||||||
* format \a fmt.
|
|
||||||
*
|
|
||||||
* See class IOFormat for some examples.
|
|
||||||
*
|
|
||||||
* \sa class IOFormat, class WithFormat
|
|
||||||
*/
|
|
||||||
inline const WithFormat<Derived> format(const IOFormat& fmt) const { return WithFormat<Derived>(derived(), fmt); }
|
|
||||||
|
|
||||||
/** \returns the unique coefficient of a 1x1 expression */
|
/** \returns the unique coefficient of a 1x1 expression */
|
||||||
EIGEN_DEVICE_FUNC CoeffReturnType value() const {
|
CoeffReturnType value() const
|
||||||
EIGEN_STATIC_ASSERT_SIZE_1x1(Derived) eigen_assert(this->rows() == 1 && this->cols() == 1);
|
{
|
||||||
|
EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
|
||||||
|
eigen_assert(this->rows() == 1 && this->cols() == 1);
|
||||||
return derived().coeff(0,0);
|
return derived().coeff(0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC bool all() const;
|
/////////// Array module ///////////
|
||||||
EIGEN_DEVICE_FUNC bool any() const;
|
|
||||||
EIGEN_DEVICE_FUNC Index count() const;
|
bool all(void) const;
|
||||||
|
bool any(void) const;
|
||||||
|
Index count() const;
|
||||||
|
|
||||||
typedef VectorwiseOp<Derived, Horizontal> RowwiseReturnType;
|
typedef VectorwiseOp<Derived, Horizontal> RowwiseReturnType;
|
||||||
typedef const VectorwiseOp<const Derived, Horizontal> ConstRowwiseReturnType;
|
typedef const VectorwiseOp<const Derived, Horizontal> ConstRowwiseReturnType;
|
||||||
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
|
ConstRowwiseReturnType rowwise() const;
|
||||||
*
|
RowwiseReturnType rowwise();
|
||||||
* Example: \include MatrixBase_rowwise.cpp
|
ConstColwiseReturnType colwise() const;
|
||||||
* Output: \verbinclude MatrixBase_rowwise.out
|
ColwiseReturnType colwise();
|
||||||
*
|
|
||||||
* \sa colwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting
|
|
||||||
*/
|
|
||||||
// Code moved here due to a CUDA compiler bug
|
|
||||||
EIGEN_DEVICE_FUNC inline ConstRowwiseReturnType rowwise() const { return ConstRowwiseReturnType(derived()); }
|
|
||||||
EIGEN_DEVICE_FUNC RowwiseReturnType rowwise();
|
|
||||||
|
|
||||||
/** \returns a VectorwiseOp wrapper of *this broadcasting and partial reductions
|
static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random(Index rows, Index cols);
|
||||||
*
|
static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random(Index size);
|
||||||
* Example: \include MatrixBase_colwise.cpp
|
static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random();
|
||||||
* Output: \verbinclude MatrixBase_colwise.out
|
|
||||||
*
|
|
||||||
* \sa rowwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC inline ConstColwiseReturnType colwise() const { return ConstColwiseReturnType(derived()); }
|
|
||||||
EIGEN_DEVICE_FUNC ColwiseReturnType colwise();
|
|
||||||
|
|
||||||
typedef CwiseNullaryOp<internal::scalar_random_op<Scalar>, PlainObject> RandomReturnType;
|
|
||||||
static const RandomReturnType Random(Index rows, Index cols);
|
|
||||||
static const RandomReturnType Random(Index size);
|
|
||||||
static const RandomReturnType Random();
|
|
||||||
|
|
||||||
template<typename ThenDerived,typename ElseDerived>
|
template<typename ThenDerived,typename ElseDerived>
|
||||||
inline EIGEN_DEVICE_FUNC constexpr CwiseTernaryOp<
|
const Select<Derived,ThenDerived,ElseDerived>
|
||||||
internal::scalar_boolean_select_op<typename DenseBase<ThenDerived>::Scalar,
|
select(const DenseBase<ThenDerived>& thenMatrix,
|
||||||
typename DenseBase<ElseDerived>::Scalar, Scalar>,
|
const DenseBase<ElseDerived>& elseMatrix) const;
|
||||||
ThenDerived, ElseDerived, Derived>
|
|
||||||
select(const DenseBase<ThenDerived>& thenMatrix, const DenseBase<ElseDerived>& elseMatrix) const;
|
|
||||||
|
|
||||||
template<typename ThenDerived>
|
template<typename ThenDerived>
|
||||||
inline EIGEN_DEVICE_FUNC constexpr CwiseTernaryOp<
|
inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
|
||||||
internal::scalar_boolean_select_op<typename DenseBase<ThenDerived>::Scalar,
|
select(const DenseBase<ThenDerived>& thenMatrix, typename ThenDerived::Scalar elseScalar) const;
|
||||||
typename DenseBase<ThenDerived>::Scalar, Scalar>,
|
|
||||||
ThenDerived, typename DenseBase<ThenDerived>::ConstantReturnType, Derived>
|
|
||||||
select(const DenseBase<ThenDerived>& thenMatrix, const typename DenseBase<ThenDerived>::Scalar& elseScalar) const;
|
|
||||||
|
|
||||||
template<typename ElseDerived>
|
template<typename ElseDerived>
|
||||||
inline EIGEN_DEVICE_FUNC constexpr CwiseTernaryOp<
|
inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
|
||||||
internal::scalar_boolean_select_op<typename DenseBase<ElseDerived>::Scalar,
|
select(typename ElseDerived::Scalar thenScalar, const DenseBase<ElseDerived>& elseMatrix) const;
|
||||||
typename DenseBase<ElseDerived>::Scalar, Scalar>,
|
|
||||||
typename DenseBase<ElseDerived>::ConstantReturnType, ElseDerived, Derived>
|
|
||||||
select(const typename DenseBase<ElseDerived>::Scalar& thenScalar, const DenseBase<ElseDerived>& elseMatrix) const;
|
|
||||||
|
|
||||||
template <int p>
|
template<int p> RealScalar lpNorm() const;
|
||||||
RealScalar lpNorm() const;
|
|
||||||
|
|
||||||
template<int RowFactor, int ColFactor>
|
template<int RowFactor, int ColFactor>
|
||||||
EIGEN_DEVICE_FUNC const Replicate<Derived, RowFactor, ColFactor> replicate() const;
|
const Replicate<Derived,RowFactor,ColFactor> replicate() const;
|
||||||
/**
|
const Replicate<Derived,Dynamic,Dynamic> replicate(Index rowFacor,Index colFactor) const;
|
||||||
* \return an expression of the replication of \c *this
|
|
||||||
*
|
|
||||||
* Example: \include MatrixBase_replicate_int_int.cpp
|
|
||||||
* Output: \verbinclude MatrixBase_replicate_int_int.out
|
|
||||||
*
|
|
||||||
* \sa VectorwiseOp::replicate(), DenseBase::replicate<int,int>(), class Replicate
|
|
||||||
*/
|
|
||||||
// Code moved here due to a CUDA compiler bug
|
|
||||||
EIGEN_DEVICE_FUNC const Replicate<Derived, Dynamic, Dynamic> replicate(Index rowFactor, Index colFactor) const {
|
|
||||||
return Replicate<Derived, Dynamic, Dynamic>(derived(), rowFactor, colFactor);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef Reverse<Derived, BothDirections> ReverseReturnType;
|
typedef Reverse<Derived, BothDirections> ReverseReturnType;
|
||||||
typedef const Reverse<const Derived, BothDirections> ConstReverseReturnType;
|
typedef const Reverse<const Derived, BothDirections> ConstReverseReturnType;
|
||||||
EIGEN_DEVICE_FUNC ReverseReturnType reverse();
|
ReverseReturnType reverse();
|
||||||
/** This is the const version of reverse(). */
|
ConstReverseReturnType reverse() const;
|
||||||
// Code moved here due to a CUDA compiler bug
|
void reverseInPlace();
|
||||||
EIGEN_DEVICE_FUNC ConstReverseReturnType reverse() const { return ConstReverseReturnType(derived()); }
|
|
||||||
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 std::conditional_t<(Flags & DirectAccessBit) == DirectAccessBit,
|
|
||||||
internal::pointer_based_stl_iterator<Derived>,
|
|
||||||
internal::generic_randaccess_stl_iterator<Derived>>
|
|
||||||
iterator_type;
|
|
||||||
|
|
||||||
typedef std::conditional_t<(Flags & DirectAccessBit) == DirectAccessBit,
|
|
||||||
internal::pointer_based_stl_iterator<const Derived>,
|
|
||||||
internal::generic_randaccess_stl_iterator<const Derived>>
|
|
||||||
const_iterator_type;
|
|
||||||
|
|
||||||
// Stl-style iterators are supported only for vectors.
|
|
||||||
|
|
||||||
typedef std::conditional_t<IsVectorAtCompileTime, iterator_type, void> iterator;
|
|
||||||
|
|
||||||
typedef std::conditional_t<IsVectorAtCompileTime, const_iterator_type, void> 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;
|
|
||||||
|
|
||||||
using RealViewReturnType = std::conditional_t<NumTraits<Scalar>::IsComplex, RealView<Derived>, Derived&>;
|
|
||||||
using ConstRealViewReturnType =
|
|
||||||
std::conditional_t<NumTraits<Scalar>::IsComplex, RealView<const Derived>, const Derived&>;
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC RealViewReturnType realView();
|
|
||||||
EIGEN_DEVICE_FUNC ConstRealViewReturnType realView() 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
|
# include "../plugins/BlockMethods.h"
|
||||||
#define EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(COND)
|
|
||||||
#define EIGEN_DOC_UNARY_ADDONS(X, Y)
|
|
||||||
#include "../plugins/CommonCwiseUnaryOps.inc"
|
|
||||||
#include "../plugins/BlockMethods.inc"
|
|
||||||
// Defines operator()(const RowIndices&, const ColIndices&) and other indexed view methods.
|
|
||||||
#include "../plugins/IndexedViewMethods.inc"
|
|
||||||
#include "../plugins/ReshapedMethods.inc"
|
|
||||||
# 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_INNER_PANEL_IF
|
#ifdef EIGEN2_SUPPORT
|
||||||
#undef EIGEN_DOC_UNARY_ADDONS
|
|
||||||
|
Block<Derived> corner(CornerType type, Index cRows, Index cCols);
|
||||||
|
const Block<Derived> corner(CornerType type, Index cRows, Index cCols) const;
|
||||||
|
template<int CRows, int CCols>
|
||||||
|
Block<Derived, CRows, CCols> corner(CornerType type);
|
||||||
|
template<int CRows, int CCols>
|
||||||
|
const Block<Derived, CRows, CCols> corner(CornerType type) const;
|
||||||
|
|
||||||
|
#endif // EIGEN2_SUPPORT
|
||||||
|
|
||||||
|
|
||||||
// disable the use of evalTo for dense objects with a nice compilation error
|
// disable the use of evalTo for dense objects with a nice compilation error
|
||||||
template <typename Dest>
|
template<typename Dest> inline void evalTo(Dest& ) const
|
||||||
EIGEN_DEVICE_FUNC inline void evalTo(Dest&) const {
|
{
|
||||||
EIGEN_STATIC_ASSERT((internal::is_same<Dest, void>::value),
|
EIGEN_STATIC_ASSERT((internal::is_same<Dest,void>::value),THE_EVAL_EVALTO_FUNCTION_SHOULD_NEVER_BE_CALLED_FOR_DENSE_OBJECTS);
|
||||||
THE_EVAL_EVALTO_FUNCTION_SHOULD_NEVER_BE_CALLED_FOR_DENSE_OBJECTS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
EIGEN_DEFAULT_COPY_CONSTRUCTOR(DenseBase)
|
|
||||||
/** Default constructor. Do nothing. */
|
/** Default constructor. Do nothing. */
|
||||||
#ifdef EIGEN_INTERNAL_DEBUGGING
|
DenseBase()
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseBase() {
|
{
|
||||||
/* Just checks for self-consistency of the flags.
|
/* Just checks for self-consistency of the flags.
|
||||||
* Only do it when debugging Eigen, as this borders on paranoia and could slow compilation down
|
* Only do it when debugging Eigen, as this borders on paranoiac and could slow compilation down
|
||||||
*/
|
*/
|
||||||
EIGEN_STATIC_ASSERT(
|
#ifdef EIGEN_INTERNAL_DEBUGGING
|
||||||
(internal::check_implication(MaxRowsAtCompileTime == 1 && MaxColsAtCompileTime != 1, int(IsRowMajor)) &&
|
EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, int(IsRowMajor))
|
||||||
internal::check_implication(MaxColsAtCompileTime == 1 && MaxRowsAtCompileTime != 1, int(!IsRowMajor))),
|
&& EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, int(!IsRowMajor))),
|
||||||
INVALID_STORAGE_ORDER_FOR_THIS_VECTOR_EXPRESSION)
|
INVALID_STORAGE_ORDER_FOR_THIS_VECTOR_EXPRESSION)
|
||||||
}
|
|
||||||
#else
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseBase() = default;
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EIGEN_DEVICE_FUNC explicit DenseBase(int);
|
explicit DenseBase(int);
|
||||||
EIGEN_DEVICE_FUNC DenseBase(int, int);
|
DenseBase(int,int);
|
||||||
template <typename OtherDerived>
|
template<typename OtherDerived> explicit DenseBase(const DenseBase<OtherDerived>&);
|
||||||
EIGEN_DEVICE_FUNC explicit DenseBase(const DenseBase<OtherDerived>&);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Free-function swap.
|
|
||||||
*/
|
|
||||||
template <typename DerivedA, typename DerivedB>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
// Use forwarding references to capture all combinations of cv-qualified l+r-value cases.
|
|
||||||
std::enable_if_t<std::is_base_of<DenseBase<std::decay_t<DerivedA>>, std::decay_t<DerivedA>>::value &&
|
|
||||||
std::is_base_of<DenseBase<std::decay_t<DerivedB>>, std::decay_t<DerivedB>>::value,
|
|
||||||
void>
|
|
||||||
swap(DerivedA&& a, DerivedB&& b) {
|
|
||||||
a.swap(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_DENSEBASE_H
|
#endif // EIGEN_DENSEBASE_H
|
||||||
|
|||||||
@@ -3,30 +3,39 @@
|
|||||||
//
|
//
|
||||||
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
|
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_DENSECOEFFSBASE_H
|
#ifndef EIGEN_DENSECOEFFSBASE_H
|
||||||
#define EIGEN_DENSECOEFFSBASE_H
|
#define EIGEN_DENSECOEFFSBASE_H
|
||||||
|
|
||||||
// IWYU pragma: private
|
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
template <typename T>
|
template<typename T> struct add_const_on_value_type_if_arithmetic
|
||||||
struct add_const_on_value_type_if_arithmetic {
|
{
|
||||||
typedef std::conditional_t<is_arithmetic<T>::value, T, add_const_on_value_type_t<T>> type;
|
typedef typename conditional<is_arithmetic<T>::value, T, typename add_const_on_value_type<T>::type>::type type;
|
||||||
};
|
};
|
||||||
} // namespace internal
|
}
|
||||||
|
|
||||||
/** \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.
|
||||||
@@ -35,9 +44,11 @@ struct add_const_on_value_type_if_arithmetic {
|
|||||||
* \ref TopicClassHierarchy
|
* \ref TopicClassHierarchy
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
class DenseCoeffsBase<Derived, ReadOnlyAccessors> : public EigenBase<Derived> {
|
class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
||||||
|
typedef typename internal::traits<Derived>::Index Index;
|
||||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||||
typedef typename internal::packet_traits<Scalar>::type PacketScalar;
|
typedef typename internal::packet_traits<Scalar>::type PacketScalar;
|
||||||
|
|
||||||
@@ -45,36 +56,34 @@ class DenseCoeffsBase<Derived, ReadOnlyAccessors> : public EigenBase<Derived> {
|
|||||||
// - This is the return type of the coeff() method.
|
// - This is the return type of the coeff() method.
|
||||||
// - The LvalueBit means exactly that we can offer a coeffRef() method, which means exactly that we can get references
|
// - The LvalueBit means exactly that we can offer a coeffRef() method, which means exactly that we can get references
|
||||||
// to coeffs, which means exactly that we can have coeff() return a const reference (as opposed to returning a value).
|
// to coeffs, which means exactly that we can have coeff() return a const reference (as opposed to returning a value).
|
||||||
// - The DirectAccessBit means exactly that the underlying data of coefficients can be directly accessed as a plain
|
// - The is_artihmetic check is required since "const int", "const double", etc. will cause warnings on some systems
|
||||||
// strided array, which means exactly that the underlying data of coefficients does exist in memory, which means
|
|
||||||
// exactly that the coefficients is const-referencable, which means exactly that we can have coeff() return a const
|
|
||||||
// reference. For example, Map<const Matrix> have DirectAccessBit but not LvalueBit, so that Map<const Matrix>.coeff()
|
|
||||||
// does points to a const Scalar& which exists in memory, while does not allow coeffRef() as it would not provide a
|
|
||||||
// lvalue. Notice that DirectAccessBit and LvalueBit are mutually orthogonal.
|
|
||||||
// - The is_arithmetic check is required since "const int", "const double", etc. will cause warnings on some systems
|
|
||||||
// while the declaration of "const T", where T is a non arithmetic type does not. Always returning "const Scalar&" is
|
// while the declaration of "const T", where T is a non arithmetic type does not. Always returning "const Scalar&" is
|
||||||
// not possible, since the underlying expressions might not offer a valid address the reference could be referring to.
|
// not possible, since the underlying expressions might not offer a valid address the reference could be referring to.
|
||||||
typedef std::conditional_t<bool(internal::traits<Derived>::Flags&(LvalueBit | DirectAccessBit)), const Scalar&,
|
typedef typename internal::conditional<bool(internal::traits<Derived>::Flags&LvalueBit),
|
||||||
std::conditional_t<internal::is_arithmetic<Scalar>::value, Scalar, const Scalar>>
|
const Scalar&,
|
||||||
CoeffReturnType;
|
typename internal::conditional<internal::is_arithmetic<Scalar>::value, Scalar, const Scalar>::type
|
||||||
|
>::type CoeffReturnType;
|
||||||
|
|
||||||
typedef typename internal::add_const_on_value_type_if_arithmetic<typename internal::packet_traits<Scalar>::type>::type
|
typedef typename internal::add_const_on_value_type_if_arithmetic<
|
||||||
PacketReturnType;
|
typename internal::packet_traits<Scalar>::type
|
||||||
|
>::type PacketReturnType;
|
||||||
|
|
||||||
typedef EigenBase<Derived> Base;
|
typedef EigenBase<Derived> Base;
|
||||||
using Base::cols;
|
|
||||||
using Base::derived;
|
|
||||||
using Base::rows;
|
using Base::rows;
|
||||||
|
using Base::cols;
|
||||||
using Base::size;
|
using Base::size;
|
||||||
|
using Base::derived;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Index rowIndexByOuterInner(Index outer, Index inner) const {
|
EIGEN_STRONG_INLINE Index rowIndexByOuterInner(Index outer, Index inner) const
|
||||||
|
{
|
||||||
return int(Derived::RowsAtCompileTime) == 1 ? 0
|
return int(Derived::RowsAtCompileTime) == 1 ? 0
|
||||||
: int(Derived::ColsAtCompileTime) == 1 ? inner
|
: int(Derived::ColsAtCompileTime) == 1 ? inner
|
||||||
: int(Derived::Flags)&RowMajorBit ? outer
|
: int(Derived::Flags)&RowMajorBit ? outer
|
||||||
: inner;
|
: inner;
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Index colIndexByOuterInner(Index outer, Index inner) const {
|
EIGEN_STRONG_INLINE Index colIndexByOuterInner(Index outer, Index inner) const
|
||||||
|
{
|
||||||
return int(Derived::ColsAtCompileTime) == 1 ? 0
|
return int(Derived::ColsAtCompileTime) == 1 ? 0
|
||||||
: int(Derived::RowsAtCompileTime) == 1 ? inner
|
: int(Derived::RowsAtCompileTime) == 1 ? inner
|
||||||
: int(Derived::Flags)&RowMajorBit ? inner
|
: int(Derived::Flags)&RowMajorBit ? inner
|
||||||
@@ -95,32 +104,30 @@ class DenseCoeffsBase<Derived, ReadOnlyAccessors> : public EigenBase<Derived> {
|
|||||||
*
|
*
|
||||||
* \sa operator()(Index,Index) const, coeffRef(Index,Index), coeff(Index) const
|
* \sa operator()(Index,Index) const, coeffRef(Index,Index), coeff(Index) const
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC constexpr CoeffReturnType coeff(Index row, Index col) const {
|
EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const
|
||||||
eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
|
{
|
||||||
return internal::evaluator<Derived>(derived()).coeff(row, col);
|
eigen_internal_assert(row >= 0 && row < rows()
|
||||||
|
&& col >= 0 && col < cols());
|
||||||
|
return derived().coeff(row, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr CoeffReturnType coeffByOuterInner(Index outer, Index inner) const {
|
EIGEN_STRONG_INLINE CoeffReturnType coeffByOuterInner(Index outer, Index inner) const
|
||||||
return coeff(rowIndexByOuterInner(outer, inner), colIndexByOuterInner(outer, inner));
|
{
|
||||||
|
return coeff(rowIndexByOuterInner(outer, inner),
|
||||||
|
colIndexByOuterInner(outer, inner));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the coefficient at given the given row and column.
|
/** \returns the coefficient at given the given row and column.
|
||||||
*
|
*
|
||||||
* \sa operator()(Index,Index), operator[](Index)
|
* \sa operator()(Index,Index), operator[](Index)
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC constexpr CoeffReturnType operator()(Index row, Index col) const {
|
EIGEN_STRONG_INLINE CoeffReturnType operator()(Index row, Index col) const
|
||||||
eigen_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
|
{
|
||||||
return coeff(row, col);
|
eigen_assert(row >= 0 && row < rows()
|
||||||
|
&& col >= 0 && col < cols());
|
||||||
|
return derived().coeff(row, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EIGEN_MULTIDIMENSIONAL_SUBSCRIPT
|
|
||||||
/** \returns the coefficient at given the given row and column.
|
|
||||||
*
|
|
||||||
* \sa operator[](Index,Index), operator[](Index)
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC constexpr CoeffReturnType operator[](Index row, Index col) const { return operator()(row, col); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Short version: don't use this function, use
|
/** Short version: don't use this function, use
|
||||||
* \link operator[](Index) const \endlink instead.
|
* \link operator[](Index) const \endlink instead.
|
||||||
*
|
*
|
||||||
@@ -136,13 +143,14 @@ class DenseCoeffsBase<Derived, ReadOnlyAccessors> : public EigenBase<Derived> {
|
|||||||
* \sa operator[](Index) const, coeffRef(Index), coeff(Index,Index) const
|
* \sa operator[](Index) const, coeffRef(Index), coeff(Index,Index) const
|
||||||
*/
|
*/
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr CoeffReturnType coeff(Index index) const {
|
EIGEN_STRONG_INLINE CoeffReturnType
|
||||||
EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
|
coeff(Index index) const
|
||||||
THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
|
{
|
||||||
eigen_internal_assert(index >= 0 && index < size());
|
eigen_internal_assert(index >= 0 && index < size());
|
||||||
return internal::evaluator<Derived>(derived()).coeff(index);
|
return derived().coeff(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** \returns the coefficient at given index.
|
/** \returns the coefficient at given index.
|
||||||
*
|
*
|
||||||
* This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
|
* This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
|
||||||
@@ -151,11 +159,15 @@ class DenseCoeffsBase<Derived, ReadOnlyAccessors> : public EigenBase<Derived> {
|
|||||||
* z() const, w() const
|
* z() const, w() const
|
||||||
*/
|
*/
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr CoeffReturnType operator[](Index index) const {
|
EIGEN_STRONG_INLINE CoeffReturnType
|
||||||
|
operator[](Index index) const
|
||||||
|
{
|
||||||
|
#ifndef EIGEN2_SUPPORT
|
||||||
EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
|
EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
|
||||||
THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
|
THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
|
||||||
|
#endif
|
||||||
eigen_assert(index >= 0 && index < size());
|
eigen_assert(index >= 0 && index < size());
|
||||||
return coeff(index);
|
return derived().coeff(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the coefficient at given index.
|
/** \returns the coefficient at given index.
|
||||||
@@ -168,35 +180,32 @@ class DenseCoeffsBase<Derived, ReadOnlyAccessors> : public EigenBase<Derived> {
|
|||||||
* z() const, w() const
|
* z() const, w() const
|
||||||
*/
|
*/
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr CoeffReturnType operator()(Index index) const {
|
EIGEN_STRONG_INLINE CoeffReturnType
|
||||||
|
operator()(Index index) const
|
||||||
|
{
|
||||||
eigen_assert(index >= 0 && index < size());
|
eigen_assert(index >= 0 && index < size());
|
||||||
return coeff(index);
|
return derived().coeff(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** equivalent to operator[](0). */
|
/** equivalent to operator[](0). */
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr CoeffReturnType x() const { return (*this)[0]; }
|
EIGEN_STRONG_INLINE CoeffReturnType
|
||||||
|
x() const { return (*this)[0]; }
|
||||||
|
|
||||||
/** equivalent to operator[](1). */
|
/** equivalent to operator[](1). */
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr CoeffReturnType y() const {
|
EIGEN_STRONG_INLINE CoeffReturnType
|
||||||
EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 2, OUT_OF_RANGE_ACCESS);
|
y() const { return (*this)[1]; }
|
||||||
return (*this)[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** equivalent to operator[](2). */
|
/** equivalent to operator[](2). */
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr CoeffReturnType z() const {
|
EIGEN_STRONG_INLINE CoeffReturnType
|
||||||
EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 3, OUT_OF_RANGE_ACCESS);
|
z() const { return (*this)[2]; }
|
||||||
return (*this)[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** equivalent to operator[](3). */
|
/** equivalent to operator[](3). */
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr CoeffReturnType w() const {
|
EIGEN_STRONG_INLINE CoeffReturnType
|
||||||
EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 4, OUT_OF_RANGE_ACCESS);
|
w() const { return (*this)[3]; }
|
||||||
return (*this)[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
* \returns the packet of coefficients starting at the given row and column. It is your responsibility
|
* \returns the packet of coefficients starting at the given row and column. It is your responsibility
|
||||||
@@ -209,16 +218,20 @@ class DenseCoeffsBase<Derived, ReadOnlyAccessors> : public EigenBase<Derived> {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
template<int LoadMode>
|
template<int LoadMode>
|
||||||
EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const {
|
EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const
|
||||||
typedef typename internal::packet_traits<Scalar>::type DefaultPacketType;
|
{
|
||||||
eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
|
eigen_internal_assert(row >= 0 && row < rows()
|
||||||
return internal::evaluator<Derived>(derived()).template packet<LoadMode, DefaultPacketType>(row, col);
|
&& col >= 0 && col < cols());
|
||||||
|
return derived().template packet<LoadMode>(row,col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** \internal */
|
/** \internal */
|
||||||
template<int LoadMode>
|
template<int LoadMode>
|
||||||
EIGEN_STRONG_INLINE PacketReturnType packetByOuterInner(Index outer, Index inner) const {
|
EIGEN_STRONG_INLINE PacketReturnType packetByOuterInner(Index outer, Index inner) const
|
||||||
return packet<LoadMode>(rowIndexByOuterInner(outer, inner), colIndexByOuterInner(outer, inner));
|
{
|
||||||
|
return packet<LoadMode>(rowIndexByOuterInner(outer, inner),
|
||||||
|
colIndexByOuterInner(outer, inner));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
@@ -232,12 +245,10 @@ class DenseCoeffsBase<Derived, ReadOnlyAccessors> : public EigenBase<Derived> {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
template<int LoadMode>
|
template<int LoadMode>
|
||||||
EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const {
|
EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
|
||||||
EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
|
{
|
||||||
THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
|
|
||||||
typedef typename internal::packet_traits<Scalar>::type DefaultPacketType;
|
|
||||||
eigen_internal_assert(index >= 0 && index < size());
|
eigen_internal_assert(index >= 0 && index < size());
|
||||||
return internal::evaluator<Derived>(derived()).template packet<LoadMode, DefaultPacketType>(index);
|
return derived().template packet<LoadMode>(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -264,8 +275,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
|
||||||
@@ -274,28 +284,31 @@ class DenseCoeffsBase<Derived, ReadOnlyAccessors> : public EigenBase<Derived> {
|
|||||||
* \sa DenseCoeffsBase<Derived, DirectAccessors>, \ref TopicClassHierarchy
|
* \sa DenseCoeffsBase<Derived, DirectAccessors>, \ref TopicClassHierarchy
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors> {
|
class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base;
|
typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base;
|
||||||
|
|
||||||
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
||||||
|
typedef typename internal::traits<Derived>::Index Index;
|
||||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||||
typedef typename internal::packet_traits<Scalar>::type PacketScalar;
|
typedef typename internal::packet_traits<Scalar>::type PacketScalar;
|
||||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||||
|
|
||||||
using Base::coeff;
|
using Base::coeff;
|
||||||
using Base::colIndexByOuterInner;
|
using Base::rows;
|
||||||
using Base::cols;
|
using Base::cols;
|
||||||
|
using Base::size;
|
||||||
using Base::derived;
|
using Base::derived;
|
||||||
using Base::rowIndexByOuterInner;
|
using Base::rowIndexByOuterInner;
|
||||||
using Base::rows;
|
using Base::colIndexByOuterInner;
|
||||||
using Base::size;
|
|
||||||
using Base::operator[];
|
using Base::operator[];
|
||||||
using Base::operator();
|
using Base::operator();
|
||||||
using Base::w;
|
|
||||||
using Base::x;
|
using Base::x;
|
||||||
using Base::y;
|
using Base::y;
|
||||||
using Base::z;
|
using Base::z;
|
||||||
|
using Base::w;
|
||||||
|
|
||||||
/** Short version: don't use this function, use
|
/** Short version: don't use this function, use
|
||||||
* \link operator()(Index,Index) \endlink instead.
|
* \link operator()(Index,Index) \endlink instead.
|
||||||
@@ -311,31 +324,33 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
|||||||
*
|
*
|
||||||
* \sa operator()(Index,Index), coeff(Index, Index) const, coeffRef(Index)
|
* \sa operator()(Index,Index), coeff(Index, Index) const, coeffRef(Index)
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC constexpr Scalar& coeffRef(Index row, Index col) {
|
EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
|
||||||
eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
|
{
|
||||||
return internal::evaluator<Derived>(derived()).coeffRef(row, col);
|
eigen_internal_assert(row >= 0 && row < rows()
|
||||||
|
&& col >= 0 && col < cols());
|
||||||
|
return derived().coeffRef(row, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Scalar& coeffRefByOuterInner(Index outer, Index inner) {
|
EIGEN_STRONG_INLINE Scalar&
|
||||||
return coeffRef(rowIndexByOuterInner(outer, inner), colIndexByOuterInner(outer, inner));
|
coeffRefByOuterInner(Index outer, Index inner)
|
||||||
|
{
|
||||||
|
return coeffRef(rowIndexByOuterInner(outer, inner),
|
||||||
|
colIndexByOuterInner(outer, inner));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns a reference to the coefficient at given the given row and column.
|
/** \returns a reference to the coefficient at given the given row and column.
|
||||||
*
|
*
|
||||||
* \sa operator[](Index)
|
* \sa operator[](Index)
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC constexpr Scalar& operator()(Index row, Index col) {
|
|
||||||
eigen_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
|
EIGEN_STRONG_INLINE Scalar&
|
||||||
return coeffRef(row, col);
|
operator()(Index row, Index col)
|
||||||
|
{
|
||||||
|
eigen_assert(row >= 0 && row < rows()
|
||||||
|
&& col >= 0 && col < cols());
|
||||||
|
return derived().coeffRef(row, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EIGEN_MULTIDIMENSIONAL_SUBSCRIPT
|
|
||||||
/** \returns a reference to the coefficient at given the given row and column.
|
|
||||||
*
|
|
||||||
* \sa operator[](Index)
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Scalar& operator[](Index row, Index col) { return operator()(row, col); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Short version: don't use this function, use
|
/** Short version: don't use this function, use
|
||||||
* \link operator[](Index) \endlink instead.
|
* \link operator[](Index) \endlink instead.
|
||||||
@@ -352,11 +367,11 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
|||||||
* \sa operator[](Index), coeff(Index) const, coeffRef(Index,Index)
|
* \sa operator[](Index), coeff(Index) const, coeffRef(Index,Index)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Scalar& coeffRef(Index index) {
|
EIGEN_STRONG_INLINE Scalar&
|
||||||
EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
|
coeffRef(Index index)
|
||||||
THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
|
{
|
||||||
eigen_internal_assert(index >= 0 && index < size());
|
eigen_internal_assert(index >= 0 && index < size());
|
||||||
return internal::evaluator<Derived>(derived()).coeffRef(index);
|
return derived().coeffRef(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns a reference to the coefficient at given index.
|
/** \returns a reference to the coefficient at given index.
|
||||||
@@ -366,11 +381,15 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
|||||||
* \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w()
|
* \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Scalar& operator[](Index index) {
|
EIGEN_STRONG_INLINE Scalar&
|
||||||
|
operator[](Index index)
|
||||||
|
{
|
||||||
|
#ifndef EIGEN2_SUPPORT
|
||||||
EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
|
EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
|
||||||
THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
|
THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
|
||||||
|
#endif
|
||||||
eigen_assert(index >= 0 && index < size());
|
eigen_assert(index >= 0 && index < size());
|
||||||
return coeffRef(index);
|
return derived().coeffRef(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns a reference to the coefficient at given index.
|
/** \returns a reference to the coefficient at given index.
|
||||||
@@ -382,135 +401,226 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
|||||||
* \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w()
|
* \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Scalar& operator()(Index index) {
|
EIGEN_STRONG_INLINE Scalar&
|
||||||
|
operator()(Index index)
|
||||||
|
{
|
||||||
eigen_assert(index >= 0 && index < size());
|
eigen_assert(index >= 0 && index < size());
|
||||||
return coeffRef(index);
|
return derived().coeffRef(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** equivalent to operator[](0). */
|
/** equivalent to operator[](0). */
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Scalar& x() { return (*this)[0]; }
|
EIGEN_STRONG_INLINE Scalar&
|
||||||
|
x() { return (*this)[0]; }
|
||||||
|
|
||||||
/** equivalent to operator[](1). */
|
/** equivalent to operator[](1). */
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Scalar& y() {
|
EIGEN_STRONG_INLINE Scalar&
|
||||||
EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 2, OUT_OF_RANGE_ACCESS);
|
y() { return (*this)[1]; }
|
||||||
return (*this)[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** equivalent to operator[](2). */
|
/** equivalent to operator[](2). */
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Scalar& z() {
|
EIGEN_STRONG_INLINE Scalar&
|
||||||
EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 3, OUT_OF_RANGE_ACCESS);
|
z() { return (*this)[2]; }
|
||||||
return (*this)[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** equivalent to operator[](3). */
|
/** equivalent to operator[](3). */
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Scalar& w() {
|
EIGEN_STRONG_INLINE Scalar&
|
||||||
EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 4, OUT_OF_RANGE_ACCESS);
|
w() { return (*this)[3]; }
|
||||||
return (*this)[3];
|
|
||||||
|
/** \internal
|
||||||
|
* Stores the given packet of coefficients, at the given row and column of this expression. It is your responsibility
|
||||||
|
* to ensure that a packet really starts there. This method is only available on expressions having the
|
||||||
|
* PacketAccessBit.
|
||||||
|
*
|
||||||
|
* The \a LoadMode parameter may have the value \a #Aligned or \a #Unaligned. Its effect is to select
|
||||||
|
* the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
|
||||||
|
* starting at an address which is a multiple of the packet size.
|
||||||
|
*/
|
||||||
|
|
||||||
|
template<int StoreMode>
|
||||||
|
EIGEN_STRONG_INLINE void writePacket
|
||||||
|
(Index row, Index col, const typename internal::packet_traits<Scalar>::type& x)
|
||||||
|
{
|
||||||
|
eigen_internal_assert(row >= 0 && row < rows()
|
||||||
|
&& col >= 0 && col < cols());
|
||||||
|
derived().template writePacket<StoreMode>(row,col,x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \internal */
|
||||||
|
template<int StoreMode>
|
||||||
|
EIGEN_STRONG_INLINE void writePacketByOuterInner
|
||||||
|
(Index outer, Index inner, const typename internal::packet_traits<Scalar>::type& x)
|
||||||
|
{
|
||||||
|
writePacket<StoreMode>(rowIndexByOuterInner(outer, inner),
|
||||||
|
colIndexByOuterInner(outer, inner),
|
||||||
|
x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \internal
|
||||||
|
* Stores the given packet of coefficients, at the given index in this expression. It is your responsibility
|
||||||
|
* to ensure that a packet really starts there. This method is only available on expressions having the
|
||||||
|
* PacketAccessBit and the LinearAccessBit.
|
||||||
|
*
|
||||||
|
* The \a LoadMode parameter may have the value \a Aligned or \a Unaligned. Its effect is to select
|
||||||
|
* the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
|
||||||
|
* starting at an address which is a multiple of the packet size.
|
||||||
|
*/
|
||||||
|
template<int StoreMode>
|
||||||
|
EIGEN_STRONG_INLINE void writePacket
|
||||||
|
(Index index, const typename internal::packet_traits<Scalar>::type& x)
|
||||||
|
{
|
||||||
|
eigen_internal_assert(index >= 0 && index < size());
|
||||||
|
derived().template writePacket<StoreMode>(index,x);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
|
||||||
|
/** \internal Copies the coefficient at position (row,col) of other into *this.
|
||||||
|
*
|
||||||
|
* This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
|
||||||
|
* with usual assignments.
|
||||||
|
*
|
||||||
|
* Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
|
||||||
|
*/
|
||||||
|
|
||||||
|
template<typename OtherDerived>
|
||||||
|
EIGEN_STRONG_INLINE void copyCoeff(Index row, Index col, const DenseBase<OtherDerived>& other)
|
||||||
|
{
|
||||||
|
eigen_internal_assert(row >= 0 && row < rows()
|
||||||
|
&& col >= 0 && col < cols());
|
||||||
|
derived().coeffRef(row, col) = other.derived().coeff(row, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \internal Copies the coefficient at the given index of other into *this.
|
||||||
|
*
|
||||||
|
* This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
|
||||||
|
* with usual assignments.
|
||||||
|
*
|
||||||
|
* Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
|
||||||
|
*/
|
||||||
|
|
||||||
|
template<typename OtherDerived>
|
||||||
|
EIGEN_STRONG_INLINE void copyCoeff(Index index, const DenseBase<OtherDerived>& other)
|
||||||
|
{
|
||||||
|
eigen_internal_assert(index >= 0 && index < size());
|
||||||
|
derived().coeffRef(index) = other.derived().coeff(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename OtherDerived>
|
||||||
|
EIGEN_STRONG_INLINE void copyCoeffByOuterInner(Index outer, Index inner, const DenseBase<OtherDerived>& other)
|
||||||
|
{
|
||||||
|
const Index row = rowIndexByOuterInner(outer,inner);
|
||||||
|
const Index col = colIndexByOuterInner(outer,inner);
|
||||||
|
// derived() is important here: copyCoeff() may be reimplemented in Derived!
|
||||||
|
derived().copyCoeff(row, col, other);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \internal Copies the packet at position (row,col) of other into *this.
|
||||||
|
*
|
||||||
|
* This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
|
||||||
|
* with usual assignments.
|
||||||
|
*
|
||||||
|
* Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
|
||||||
|
*/
|
||||||
|
|
||||||
|
template<typename OtherDerived, int StoreMode, int LoadMode>
|
||||||
|
EIGEN_STRONG_INLINE void copyPacket(Index row, Index col, const DenseBase<OtherDerived>& other)
|
||||||
|
{
|
||||||
|
eigen_internal_assert(row >= 0 && row < rows()
|
||||||
|
&& col >= 0 && col < cols());
|
||||||
|
derived().template writePacket<StoreMode>(row, col,
|
||||||
|
other.derived().template packet<LoadMode>(row, col));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \internal Copies the packet at the given index of other into *this.
|
||||||
|
*
|
||||||
|
* This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
|
||||||
|
* with usual assignments.
|
||||||
|
*
|
||||||
|
* Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
|
||||||
|
*/
|
||||||
|
|
||||||
|
template<typename OtherDerived, int StoreMode, int LoadMode>
|
||||||
|
EIGEN_STRONG_INLINE void copyPacket(Index index, const DenseBase<OtherDerived>& other)
|
||||||
|
{
|
||||||
|
eigen_internal_assert(index >= 0 && index < size());
|
||||||
|
derived().template writePacket<StoreMode>(index,
|
||||||
|
other.derived().template packet<LoadMode>(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \internal */
|
||||||
|
template<typename OtherDerived, int StoreMode, int LoadMode>
|
||||||
|
EIGEN_STRONG_INLINE void copyPacketByOuterInner(Index outer, Index inner, const DenseBase<OtherDerived>& other)
|
||||||
|
{
|
||||||
|
const Index row = rowIndexByOuterInner(outer,inner);
|
||||||
|
const Index col = colIndexByOuterInner(outer,inner);
|
||||||
|
// derived() is important here: copyCoeff() may be reimplemented in Derived!
|
||||||
|
derived().template copyPacket< OtherDerived, StoreMode, LoadMode>(row, col, other);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \brief Base class providing direct read-only coefficient access to matrices and arrays.
|
/** \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
|
||||||
* \c operator() .
|
* \c operator() .
|
||||||
*
|
*
|
||||||
* \sa \blank \ref TopicClassHierarchy
|
* \sa \ref TopicClassHierarchy
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors> {
|
class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base;
|
typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base;
|
||||||
|
typedef typename internal::traits<Derived>::Index Index;
|
||||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||||
|
|
||||||
using Base::cols;
|
|
||||||
using Base::derived;
|
|
||||||
using Base::rows;
|
using Base::rows;
|
||||||
|
using Base::cols;
|
||||||
using Base::size;
|
using Base::size;
|
||||||
|
using Base::derived;
|
||||||
|
|
||||||
/** \returns the pointer increment between two consecutive elements within a slice in the inner direction.
|
/** \returns the pointer increment between two consecutive elements within a slice in the inner direction.
|
||||||
*
|
*
|
||||||
* \sa outerStride(), rowStride(), colStride()
|
* \sa outerStride(), rowStride(), colStride()
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC constexpr Index innerStride() const { return derived().innerStride(); }
|
inline Index innerStride() const
|
||||||
|
{
|
||||||
|
return derived().innerStride();
|
||||||
|
}
|
||||||
|
|
||||||
/** \returns the pointer increment between two consecutive inner slices (for example, between two consecutive columns
|
/** \returns the pointer increment between two consecutive inner slices (for example, between two consecutive columns
|
||||||
* in a column-major matrix).
|
* in a column-major matrix).
|
||||||
*
|
*
|
||||||
* \sa innerStride(), rowStride(), colStride()
|
* \sa innerStride(), rowStride(), colStride()
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC constexpr Index outerStride() const { return derived().outerStride(); }
|
inline Index outerStride() const
|
||||||
|
{
|
||||||
|
return derived().outerStride();
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME shall we remove it ?
|
// FIXME shall we remove it ?
|
||||||
constexpr Index stride() const { return Derived::IsVectorAtCompileTime ? innerStride() : outerStride(); }
|
inline Index stride() const
|
||||||
|
{
|
||||||
|
return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
|
||||||
|
}
|
||||||
|
|
||||||
/** \returns the pointer increment between two consecutive rows.
|
/** \returns the pointer increment between two consecutive rows.
|
||||||
*
|
*
|
||||||
* \sa innerStride(), outerStride(), colStride()
|
* \sa innerStride(), outerStride(), colStride()
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC constexpr Index rowStride() const { return Derived::IsRowMajor ? outerStride() : innerStride(); }
|
inline Index rowStride() const
|
||||||
|
{
|
||||||
/** \returns the pointer increment between two consecutive columns.
|
|
||||||
*
|
|
||||||
* \sa innerStride(), outerStride(), rowStride()
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index colStride() const { return Derived::IsRowMajor ? innerStride() : outerStride(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \brief Base class providing direct read/write coefficient access to matrices and arrays.
|
|
||||||
* \ingroup Core_Module
|
|
||||||
* \tparam Derived Type of the derived class
|
|
||||||
*
|
|
||||||
* \note #DirectWriteAccessors Constant indicating direct access
|
|
||||||
*
|
|
||||||
* This class defines functions to work with strides which can be used to access entries directly. This class
|
|
||||||
* inherits DenseCoeffsBase<Derived, WriteAccessors> which defines functions to access entries read/write using
|
|
||||||
* \c operator().
|
|
||||||
*
|
|
||||||
* \sa \blank \ref TopicClassHierarchy
|
|
||||||
*/
|
|
||||||
template <typename Derived>
|
|
||||||
class DenseCoeffsBase<Derived, DirectWriteAccessors> : public DenseCoeffsBase<Derived, WriteAccessors> {
|
|
||||||
public:
|
|
||||||
typedef DenseCoeffsBase<Derived, WriteAccessors> Base;
|
|
||||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
|
||||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
|
||||||
|
|
||||||
using Base::cols;
|
|
||||||
using Base::derived;
|
|
||||||
using Base::rows;
|
|
||||||
using Base::size;
|
|
||||||
|
|
||||||
/** \returns the pointer increment between two consecutive elements within a slice in the inner direction.
|
|
||||||
*
|
|
||||||
* \sa outerStride(), rowStride(), colStride()
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index innerStride() const noexcept { return derived().innerStride(); }
|
|
||||||
|
|
||||||
/** \returns the pointer increment between two consecutive inner slices (for example, between two consecutive columns
|
|
||||||
* in a column-major matrix).
|
|
||||||
*
|
|
||||||
* \sa innerStride(), rowStride(), colStride()
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index outerStride() const noexcept { return derived().outerStride(); }
|
|
||||||
|
|
||||||
// FIXME shall we remove it ?
|
|
||||||
constexpr Index stride() const noexcept { return Derived::IsVectorAtCompileTime ? innerStride() : outerStride(); }
|
|
||||||
|
|
||||||
/** \returns the pointer increment between two consecutive rows.
|
|
||||||
*
|
|
||||||
* \sa innerStride(), outerStride(), colStride()
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index rowStride() const noexcept {
|
|
||||||
return Derived::IsRowMajor ? outerStride() : innerStride();
|
return Derived::IsRowMajor ? outerStride() : innerStride();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,66 +628,138 @@ class DenseCoeffsBase<Derived, DirectWriteAccessors> : public DenseCoeffsBase<De
|
|||||||
*
|
*
|
||||||
* \sa innerStride(), outerStride(), rowStride()
|
* \sa innerStride(), outerStride(), rowStride()
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC constexpr Index colStride() const noexcept {
|
inline Index colStride() const
|
||||||
|
{
|
||||||
|
return Derived::IsRowMajor ? innerStride() : outerStride();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** \brief Base class providing direct read/write coefficient access to matrices and arrays.
|
||||||
|
* \ingroup Core_Module
|
||||||
|
* \tparam Derived Type of the derived class
|
||||||
|
* \tparam #DirectWriteAccessors Constant indicating direct access
|
||||||
|
*
|
||||||
|
* This class defines functions to work with strides which can be used to access entries directly. This class
|
||||||
|
* inherits DenseCoeffsBase<Derived, WriteAccessors> which defines functions to access entries read/write using
|
||||||
|
* \c operator().
|
||||||
|
*
|
||||||
|
* \sa \ref TopicClassHierarchy
|
||||||
|
*/
|
||||||
|
template<typename Derived>
|
||||||
|
class DenseCoeffsBase<Derived, DirectWriteAccessors>
|
||||||
|
: public DenseCoeffsBase<Derived, WriteAccessors>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef DenseCoeffsBase<Derived, WriteAccessors> Base;
|
||||||
|
typedef typename internal::traits<Derived>::Index Index;
|
||||||
|
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||||
|
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||||
|
|
||||||
|
using Base::rows;
|
||||||
|
using Base::cols;
|
||||||
|
using Base::size;
|
||||||
|
using Base::derived;
|
||||||
|
|
||||||
|
/** \returns the pointer increment between two consecutive elements within a slice in the inner direction.
|
||||||
|
*
|
||||||
|
* \sa outerStride(), rowStride(), colStride()
|
||||||
|
*/
|
||||||
|
inline Index innerStride() const
|
||||||
|
{
|
||||||
|
return derived().innerStride();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \returns the pointer increment between two consecutive inner slices (for example, between two consecutive columns
|
||||||
|
* in a column-major matrix).
|
||||||
|
*
|
||||||
|
* \sa innerStride(), rowStride(), colStride()
|
||||||
|
*/
|
||||||
|
inline Index outerStride() const
|
||||||
|
{
|
||||||
|
return derived().outerStride();
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME shall we remove it ?
|
||||||
|
inline Index stride() const
|
||||||
|
{
|
||||||
|
return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \returns the pointer increment between two consecutive rows.
|
||||||
|
*
|
||||||
|
* \sa innerStride(), outerStride(), colStride()
|
||||||
|
*/
|
||||||
|
inline Index rowStride() const
|
||||||
|
{
|
||||||
|
return Derived::IsRowMajor ? outerStride() : innerStride();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \returns the pointer increment between two consecutive columns.
|
||||||
|
*
|
||||||
|
* \sa innerStride(), outerStride(), rowStride()
|
||||||
|
*/
|
||||||
|
inline Index colStride() const
|
||||||
|
{
|
||||||
return Derived::IsRowMajor ? innerStride() : outerStride();
|
return Derived::IsRowMajor ? innerStride() : outerStride();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template <int Alignment, typename Derived, bool JustReturnZero>
|
template<typename Derived, bool JustReturnZero>
|
||||||
struct first_aligned_impl {
|
struct first_aligned_impl
|
||||||
static constexpr Index run(const Derived&) noexcept { return 0; }
|
{
|
||||||
|
inline static typename Derived::Index run(const Derived&)
|
||||||
|
{ return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <int Alignment, typename Derived>
|
template<typename Derived>
|
||||||
struct first_aligned_impl<Alignment, Derived, false> {
|
struct first_aligned_impl<Derived, false>
|
||||||
static inline Index run(const Derived& m) { return internal::first_aligned<Alignment>(m.data(), m.size()); }
|
{
|
||||||
|
inline static typename Derived::Index run(const Derived& m)
|
||||||
|
{
|
||||||
|
return first_aligned(&m.const_cast_derived().coeffRef(0,0), m.size());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \internal \returns the index of the first element of the array stored by \a m that is properly aligned with respect
|
/** \internal \returns the index of the first element of the array that is well aligned for vectorization.
|
||||||
* to \a Alignment for vectorization.
|
|
||||||
*
|
|
||||||
* \tparam Alignment requested alignment in Bytes.
|
|
||||||
*
|
*
|
||||||
* There is also the variant first_aligned(const Scalar*, Integer) defined in Memory.h. See it for more
|
* There is also the variant first_aligned(const Scalar*, Integer) defined in Memory.h. See it for more
|
||||||
* documentation.
|
* documentation.
|
||||||
*/
|
*/
|
||||||
template <int Alignment, typename Derived>
|
|
||||||
static inline Index first_aligned(const DenseBase<Derived>& m) {
|
|
||||||
enum { ReturnZero = (int(evaluator<Derived>::Alignment) >= Alignment) || !(Derived::Flags & DirectAccessBit) };
|
|
||||||
return first_aligned_impl<Alignment, Derived, ReturnZero>::run(m.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
static inline Index first_default_aligned(const DenseBase<Derived>& m) {
|
inline static typename Derived::Index first_aligned(const Derived& m)
|
||||||
typedef typename Derived::Scalar Scalar;
|
{
|
||||||
typedef typename packet_traits<Scalar>::type DefaultPacketType;
|
return first_aligned_impl
|
||||||
return internal::first_aligned<int(unpacket_traits<DefaultPacketType>::alignment), Derived>(m);
|
<Derived, (Derived::Flags & AlignedBit) || !(Derived::Flags & DirectAccessBit)>
|
||||||
|
::run(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
|
template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
|
||||||
struct inner_stride_at_compile_time {
|
struct inner_stride_at_compile_time
|
||||||
|
{
|
||||||
enum { ret = traits<Derived>::InnerStrideAtCompileTime };
|
enum { ret = traits<Derived>::InnerStrideAtCompileTime };
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
struct inner_stride_at_compile_time<Derived, false> {
|
struct inner_stride_at_compile_time<Derived, false>
|
||||||
|
{
|
||||||
enum { ret = 0 };
|
enum { ret = 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
|
template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
|
||||||
struct outer_stride_at_compile_time {
|
struct outer_stride_at_compile_time
|
||||||
|
{
|
||||||
enum { ret = traits<Derived>::OuterStrideAtCompileTime };
|
enum { ret = traits<Derived>::OuterStrideAtCompileTime };
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
struct outer_stride_at_compile_time<Derived, false> {
|
struct outer_stride_at_compile_time<Derived, false>
|
||||||
|
{
|
||||||
enum { ret = 0 };
|
enum { ret = 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_DENSECOEFFSBASE_H
|
#endif // EIGEN_DENSECOEFFSBASE_H
|
||||||
|
|||||||
@@ -3,500 +3,86 @@
|
|||||||
//
|
//
|
||||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
// Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
|
// Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||||
// Copyright (C) 2010-2013 Hauke Heibel <hauke.heibel@gmail.com>
|
// Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.com>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_MATRIXSTORAGE_H
|
#ifndef EIGEN_MATRIXSTORAGE_H
|
||||||
#define EIGEN_MATRIXSTORAGE_H
|
#define EIGEN_MATRIXSTORAGE_H
|
||||||
|
|
||||||
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||||
#define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(X) \
|
#define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN EIGEN_DENSE_STORAGE_CTOR_PLUGIN;
|
||||||
X; \
|
|
||||||
EIGEN_DENSE_STORAGE_CTOR_PLUGIN;
|
|
||||||
#else
|
#else
|
||||||
#define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(X)
|
#define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// IWYU pragma: private
|
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
#if defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT)
|
struct constructor_without_unaligned_array_assert {};
|
||||||
#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(Alignment)
|
|
||||||
#else
|
|
||||||
#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(Alignment) \
|
|
||||||
eigen_assert((is_constant_evaluated() || (std::uintptr_t(array) % Alignment == 0)) && \
|
|
||||||
"this assertion is explained here: " \
|
|
||||||
"http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \
|
|
||||||
" **** READ THIS WEB PAGE !!! ****");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if EIGEN_STACK_ALLOCATION_LIMIT
|
|
||||||
#define EIGEN_MAKE_STACK_ALLOCATION_ASSERT(X) \
|
|
||||||
EIGEN_STATIC_ASSERT(X <= EIGEN_STACK_ALLOCATION_LIMIT, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG)
|
|
||||||
#else
|
|
||||||
#define EIGEN_MAKE_STACK_ALLOCATION_ASSERT(X)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
* Static array. If the MatrixOrArrayOptions require auto-alignment, the array will be automatically aligned:
|
* Static array. If the MatrixOrArrayOptions require auto-alignment, the array will be automatically aligned:
|
||||||
* to 16 bytes boundary if the total size is a multiple of 16 bytes.
|
* to 16 bytes boundary if the total size is a multiple of 16 bytes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <typename T, int Size, int MatrixOrArrayOptions,
|
template <typename T, int Size, int MatrixOrArrayOptions,
|
||||||
int Alignment = (MatrixOrArrayOptions & DontAlign) ? 0 : compute_default_alignment<T, Size>::value>
|
int Alignment = (MatrixOrArrayOptions&DontAlign) ? 0
|
||||||
struct plain_array {
|
: (((Size*sizeof(T))%16)==0) ? 16
|
||||||
EIGEN_ALIGN_TO_BOUNDARY(Alignment) T array[Size];
|
: 0 >
|
||||||
#if defined(EIGEN_NO_DEBUG) || defined(EIGEN_TESTING_PLAINOBJECT_CTOR)
|
struct plain_array
|
||||||
EIGEN_DEVICE_FUNC constexpr plain_array() = default;
|
{
|
||||||
#else
|
T array[Size];
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr plain_array() {
|
plain_array() {}
|
||||||
EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(Alignment)
|
plain_array(constructor_without_unaligned_array_assert) {}
|
||||||
EIGEN_MAKE_STACK_ALLOCATION_ASSERT(Size * sizeof(T))
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
|
||||||
|
#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask)
|
||||||
|
#else
|
||||||
|
#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \
|
||||||
|
eigen_assert((reinterpret_cast<size_t>(array) & sizemask) == 0 \
|
||||||
|
&& "this assertion is explained here: " \
|
||||||
|
"http://eigen.tuxfamily.org/dox-devel/TopicUnalignedArrayAssert.html" \
|
||||||
|
" **** READ THIS WEB PAGE !!! ****");
|
||||||
|
#endif
|
||||||
|
|
||||||
template <typename T, int Size, int MatrixOrArrayOptions>
|
template <typename T, int Size, int MatrixOrArrayOptions>
|
||||||
struct plain_array<T, Size, MatrixOrArrayOptions, 0> {
|
struct plain_array<T, Size, MatrixOrArrayOptions, 16>
|
||||||
// on some 32-bit platforms, stack-allocated arrays are aligned to 4 bytes, not the preferred alignment of T
|
{
|
||||||
EIGEN_ALIGN_TO_BOUNDARY(alignof(T)) T array[Size];
|
EIGEN_USER_ALIGN16 T array[Size];
|
||||||
#if defined(EIGEN_NO_DEBUG) || defined(EIGEN_TESTING_PLAINOBJECT_CTOR)
|
plain_array() { EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(0xf) }
|
||||||
EIGEN_DEVICE_FUNC constexpr plain_array() = default;
|
plain_array(constructor_without_unaligned_array_assert) {}
|
||||||
#else
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr plain_array() { EIGEN_MAKE_STACK_ALLOCATION_ASSERT(Size * sizeof(T)) }
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, int Size, int Options, int Alignment>
|
template <typename T, int MatrixOrArrayOptions, int Alignment>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void swap_plain_array(plain_array<T, Size, Options, Alignment>& a,
|
struct plain_array<T, 0, MatrixOrArrayOptions, Alignment>
|
||||||
plain_array<T, Size, Options, Alignment>& b,
|
{
|
||||||
Index a_size, Index b_size) {
|
EIGEN_USER_ALIGN16 T array[1];
|
||||||
Index common_size = numext::mini(a_size, b_size);
|
plain_array() {}
|
||||||
std::swap_ranges(a.array, a.array + common_size, b.array);
|
plain_array(constructor_without_unaligned_array_assert) {}
|
||||||
if (a_size > b_size)
|
};
|
||||||
smart_copy(a.array + common_size, a.array + a_size, b.array + common_size);
|
|
||||||
else if (b_size > a_size)
|
|
||||||
smart_copy(b.array + common_size, b.array + b_size, a.array + common_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, int Size, int Rows, int Cols, int Options>
|
|
||||||
class DenseStorage_impl {
|
|
||||||
plain_array<T, Size, Options> m_data;
|
|
||||||
|
|
||||||
public:
|
|
||||||
#ifndef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl() = default;
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl(const DenseStorage_impl&) = default;
|
|
||||||
#else
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage_impl() {
|
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size)
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage_impl(const DenseStorage_impl& other) {
|
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size)
|
|
||||||
smart_copy(other.m_data.array, other.m_data.array + Size, m_data.array);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl(Index /*size*/, Index /*rows*/, Index /*cols*/) {}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl& operator=(const DenseStorage_impl&) = default;
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void swap(DenseStorage_impl& other) {
|
|
||||||
numext::swap(m_data, other.m_data);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr void conservativeResize(Index /*size*/, Index /*rows*/, Index /*cols*/) {}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr void resize(Index /*size*/, Index /*rows*/, Index /*cols*/) {}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index rows() const { return Rows; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index cols() const { return Cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index size() const { return Rows * Cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr T* data() { return m_data.array; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr const T* data() const { return m_data.array; }
|
|
||||||
};
|
|
||||||
template <typename T, int Size, int Cols, int Options>
|
|
||||||
class DenseStorage_impl<T, Size, Dynamic, Cols, Options> {
|
|
||||||
plain_array<T, Size, Options> m_data;
|
|
||||||
Index m_rows = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl() = default;
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage_impl(const DenseStorage_impl& other)
|
|
||||||
: m_rows(other.m_rows) {
|
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = other.size())
|
|
||||||
smart_copy(other.m_data.array, other.m_data.array + other.size(), m_data.array);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage_impl(Index size, Index rows, Index /*cols*/)
|
|
||||||
: m_rows(rows) {
|
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
|
|
||||||
EIGEN_UNUSED_VARIABLE(size);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage_impl& operator=(const DenseStorage_impl& other) {
|
|
||||||
smart_copy(other.m_data.array, other.m_data.array + other.size(), m_data.array);
|
|
||||||
m_rows = other.m_rows;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void swap(DenseStorage_impl& other) {
|
|
||||||
swap_plain_array(m_data, other.m_data, size(), other.size());
|
|
||||||
numext::swap(m_rows, other.m_rows);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr void conservativeResize(Index /*size*/, Index rows, Index /*cols*/) { m_rows = rows; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr void resize(Index /*size*/, Index rows, Index /*cols*/) { m_rows = rows; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index rows() const { return m_rows; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index cols() const { return Cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index size() const { return m_rows * Cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr T* data() { return m_data.array; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr const T* data() const { return m_data.array; }
|
|
||||||
};
|
|
||||||
template <typename T, int Size, int Rows, int Options>
|
|
||||||
class DenseStorage_impl<T, Size, Rows, Dynamic, Options> {
|
|
||||||
plain_array<T, Size, Options> m_data;
|
|
||||||
Index m_cols = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl() = default;
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage_impl(const DenseStorage_impl& other)
|
|
||||||
: m_cols(other.m_cols) {
|
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = other.size())
|
|
||||||
smart_copy(other.m_data.array, other.m_data.array + other.size(), m_data.array);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage_impl(Index size, Index /*rows*/, Index cols)
|
|
||||||
: m_cols(cols) {
|
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
|
|
||||||
EIGEN_UNUSED_VARIABLE(size);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage_impl& operator=(const DenseStorage_impl& other) {
|
|
||||||
smart_copy(other.m_data.array, other.m_data.array + other.size(), m_data.array);
|
|
||||||
m_cols = other.m_cols;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void swap(DenseStorage_impl& other) {
|
|
||||||
swap_plain_array(m_data, other.m_data, size(), other.size());
|
|
||||||
numext::swap(m_cols, other.m_cols);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr void conservativeResize(Index /*size*/, Index /*rows*/, Index cols) { m_cols = cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr void resize(Index /*size*/, Index /*rows*/, Index cols) { m_cols = cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index rows() const { return Rows; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index cols() const { return m_cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index size() const { return Rows * m_cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr T* data() { return m_data.array; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr const T* data() const { return m_data.array; }
|
|
||||||
};
|
|
||||||
template <typename T, int Size, int Options>
|
|
||||||
class DenseStorage_impl<T, Size, Dynamic, Dynamic, Options> {
|
|
||||||
plain_array<T, Size, Options> m_data;
|
|
||||||
Index m_rows = 0;
|
|
||||||
Index m_cols = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl() = default;
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage_impl(const DenseStorage_impl& other)
|
|
||||||
: m_rows(other.m_rows), m_cols(other.m_cols) {
|
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = other.size())
|
|
||||||
smart_copy(other.m_data.array, other.m_data.array + other.size(), m_data.array);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage_impl(Index size, Index rows, Index cols)
|
|
||||||
: m_rows(rows), m_cols(cols) {
|
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
|
|
||||||
EIGEN_UNUSED_VARIABLE(size);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage_impl& operator=(const DenseStorage_impl& other) {
|
|
||||||
smart_copy(other.m_data.array, other.m_data.array + other.size(), m_data.array);
|
|
||||||
m_rows = other.m_rows;
|
|
||||||
m_cols = other.m_cols;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void swap(DenseStorage_impl& other) {
|
|
||||||
swap_plain_array(m_data, other.m_data, size(), other.size());
|
|
||||||
numext::swap(m_rows, other.m_rows);
|
|
||||||
numext::swap(m_cols, other.m_cols);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr void conservativeResize(Index /*size*/, Index rows, Index cols) {
|
|
||||||
m_rows = rows;
|
|
||||||
m_cols = cols;
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr void resize(Index /*size*/, Index rows, Index cols) {
|
|
||||||
m_rows = rows;
|
|
||||||
m_cols = cols;
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index rows() const { return m_rows; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index cols() const { return m_cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index size() const { return m_rows * m_cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr T* data() { return m_data.array; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr const T* data() const { return m_data.array; }
|
|
||||||
};
|
|
||||||
// null matrix variants
|
|
||||||
template <typename T, int Rows, int Cols, int Options>
|
|
||||||
class DenseStorage_impl<T, 0, Rows, Cols, Options> {
|
|
||||||
public:
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl() = default;
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl(const DenseStorage_impl&) = default;
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl(Index /*size*/, Index /*rows*/, Index /*cols*/) {}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl& operator=(const DenseStorage_impl&) = default;
|
|
||||||
EIGEN_DEVICE_FUNC constexpr void swap(DenseStorage_impl&) {}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr void conservativeResize(Index /*size*/, Index /*rows*/, Index /*cols*/) {}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr void resize(Index /*size*/, Index /*rows*/, Index /*cols*/) {}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index rows() const { return Rows; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index cols() const { return Cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index size() const { return Rows * Cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr T* data() { return nullptr; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr const T* data() const { return nullptr; }
|
|
||||||
};
|
|
||||||
template <typename T, int Cols, int Options>
|
|
||||||
class DenseStorage_impl<T, 0, Dynamic, Cols, Options> {
|
|
||||||
Index m_rows = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl() = default;
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl(const DenseStorage_impl&) = default;
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl(Index /*size*/, Index rows, Index /*cols*/) : m_rows(rows) {}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl& operator=(const DenseStorage_impl&) = default;
|
|
||||||
EIGEN_DEVICE_FUNC constexpr void swap(DenseStorage_impl& other) noexcept { numext::swap(m_rows, other.m_rows); }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr void conservativeResize(Index /*size*/, Index rows, Index /*cols*/) { m_rows = rows; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr void resize(Index /*size*/, Index rows, Index /*cols*/) { m_rows = rows; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index rows() const { return m_rows; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index cols() const { return Cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index size() const { return m_rows * Cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr T* data() { return nullptr; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr const T* data() const { return nullptr; }
|
|
||||||
};
|
|
||||||
template <typename T, int Rows, int Options>
|
|
||||||
class DenseStorage_impl<T, 0, Rows, Dynamic, Options> {
|
|
||||||
Index m_cols = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl() = default;
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl(const DenseStorage_impl&) = default;
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl(Index /*size*/, Index /*rows*/, Index cols) : m_cols(cols) {}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl& operator=(const DenseStorage_impl&) = default;
|
|
||||||
EIGEN_DEVICE_FUNC constexpr void swap(DenseStorage_impl& other) noexcept { numext::swap(m_cols, other.m_cols); }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr void conservativeResize(Index /*size*/, Index /*rows*/, Index cols) { m_cols = cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr void resize(Index /*size*/, Index /*rows*/, Index cols) { m_cols = cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index rows() const { return Rows; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index cols() const { return m_cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index size() const { return Rows * m_cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr T* data() { return nullptr; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr const T* data() const { return nullptr; }
|
|
||||||
};
|
|
||||||
template <typename T, int Options>
|
|
||||||
class DenseStorage_impl<T, 0, Dynamic, Dynamic, Options> {
|
|
||||||
Index m_rows = 0;
|
|
||||||
Index m_cols = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl() = default;
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl(const DenseStorage_impl&) = default;
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl(Index /*size*/, Index rows, Index cols) : m_rows(rows), m_cols(cols) {}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl& operator=(const DenseStorage_impl&) = default;
|
|
||||||
EIGEN_DEVICE_FUNC constexpr void swap(DenseStorage_impl& other) noexcept {
|
|
||||||
numext::swap(m_rows, other.m_rows);
|
|
||||||
numext::swap(m_cols, other.m_cols);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr void conservativeResize(Index /*size*/, Index rows, Index cols) {
|
|
||||||
m_rows = rows;
|
|
||||||
m_cols = cols;
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr void resize(Index /*size*/, Index rows, Index cols) {
|
|
||||||
m_rows = rows;
|
|
||||||
m_cols = cols;
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index rows() const { return m_rows; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index cols() const { return m_cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index size() const { return m_rows * m_cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr T* data() { return nullptr; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr const T* data() const { return nullptr; }
|
|
||||||
};
|
|
||||||
// fixed-size matrix with dynamic memory allocation not currently supported
|
|
||||||
template <typename T, int Rows, int Cols, int Options>
|
|
||||||
class DenseStorage_impl<T, Dynamic, Rows, Cols, Options> {};
|
|
||||||
// dynamic-sized variants
|
|
||||||
template <typename T, int Cols, int Options>
|
|
||||||
class DenseStorage_impl<T, Dynamic, Dynamic, Cols, Options> {
|
|
||||||
static constexpr bool Align = (Options & DontAlign) == 0;
|
|
||||||
T* m_data = nullptr;
|
|
||||||
Index m_rows = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static constexpr int Size = Dynamic;
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl() = default;
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage_impl(const DenseStorage_impl& other)
|
|
||||||
: m_data(conditional_aligned_new_auto<T, Align>(other.size())), m_rows(other.m_rows) {
|
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = other.size())
|
|
||||||
smart_copy(other.m_data, other.m_data + other.size(), m_data);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage_impl(Index size, Index rows, Index /*cols*/)
|
|
||||||
: m_data(conditional_aligned_new_auto<T, Align>(size)), m_rows(rows) {
|
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl(DenseStorage_impl&& other) noexcept
|
|
||||||
: m_data(other.m_data), m_rows(other.m_rows) {
|
|
||||||
other.m_data = nullptr;
|
|
||||||
other.m_rows = 0;
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC ~DenseStorage_impl() { conditional_aligned_delete_auto<T, Align>(m_data, size()); }
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage_impl& operator=(const DenseStorage_impl& other) {
|
|
||||||
resize(other.size(), other.rows(), other.cols());
|
|
||||||
smart_copy(other.m_data, other.m_data + other.size(), m_data);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl& operator=(DenseStorage_impl&& other) noexcept {
|
|
||||||
this->swap(other);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr void swap(DenseStorage_impl& other) noexcept {
|
|
||||||
numext::swap(m_data, other.m_data);
|
|
||||||
numext::swap(m_rows, other.m_rows);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void conservativeResize(Index size, Index rows, Index /*cols*/) {
|
|
||||||
m_data = conditional_aligned_realloc_new_auto<T, Align>(m_data, size, this->size());
|
|
||||||
m_rows = rows;
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void resize(Index size, Index rows, Index /*cols*/) {
|
|
||||||
Index oldSize = this->size();
|
|
||||||
if (oldSize != size) {
|
|
||||||
conditional_aligned_delete_auto<T, Align>(m_data, oldSize);
|
|
||||||
m_data = conditional_aligned_new_auto<T, Align>(size);
|
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
|
|
||||||
}
|
|
||||||
m_rows = rows;
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index rows() const { return m_rows; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index cols() const { return Cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index size() const { return m_rows * Cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr T* data() { return m_data; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr const T* data() const { return m_data; }
|
|
||||||
};
|
|
||||||
template <typename T, int Rows, int Options>
|
|
||||||
class DenseStorage_impl<T, Dynamic, Rows, Dynamic, Options> {
|
|
||||||
static constexpr bool Align = (Options & DontAlign) == 0;
|
|
||||||
T* m_data = nullptr;
|
|
||||||
Index m_cols = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static constexpr int Size = Dynamic;
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl() = default;
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage_impl(const DenseStorage_impl& other)
|
|
||||||
: m_data(conditional_aligned_new_auto<T, Align>(other.size())), m_cols(other.m_cols) {
|
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = other.size())
|
|
||||||
smart_copy(other.m_data, other.m_data + other.size(), m_data);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage_impl(Index size, Index /*rows*/, Index cols)
|
|
||||||
: m_data(conditional_aligned_new_auto<T, Align>(size)), m_cols(cols) {
|
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl(DenseStorage_impl&& other) noexcept
|
|
||||||
: m_data(other.m_data), m_cols(other.m_cols) {
|
|
||||||
other.m_data = nullptr;
|
|
||||||
other.m_cols = 0;
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC ~DenseStorage_impl() { conditional_aligned_delete_auto<T, Align>(m_data, size()); }
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage_impl& operator=(const DenseStorage_impl& other) {
|
|
||||||
resize(other.size(), other.rows(), other.cols());
|
|
||||||
smart_copy(other.m_data, other.m_data + other.size(), m_data);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl& operator=(DenseStorage_impl&& other) noexcept {
|
|
||||||
this->swap(other);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr void swap(DenseStorage_impl& other) noexcept {
|
|
||||||
numext::swap(m_data, other.m_data);
|
|
||||||
numext::swap(m_cols, other.m_cols);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void conservativeResize(Index size, Index /*rows*/, Index cols) {
|
|
||||||
m_data = conditional_aligned_realloc_new_auto<T, Align>(m_data, size, this->size());
|
|
||||||
m_cols = cols;
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void resize(Index size, Index /*rows*/, Index cols) {
|
|
||||||
Index oldSize = this->size();
|
|
||||||
if (oldSize != size) {
|
|
||||||
conditional_aligned_delete_auto<T, Align>(m_data, oldSize);
|
|
||||||
m_data = conditional_aligned_new_auto<T, Align>(size);
|
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
|
|
||||||
}
|
|
||||||
m_cols = cols;
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index rows() const { return Rows; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index cols() const { return m_cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index size() const { return Rows * m_cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr T* data() { return m_data; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr const T* data() const { return m_data; }
|
|
||||||
};
|
|
||||||
template <typename T, int Options>
|
|
||||||
class DenseStorage_impl<T, Dynamic, Dynamic, Dynamic, Options> {
|
|
||||||
static constexpr bool Align = (Options & DontAlign) == 0;
|
|
||||||
T* m_data = nullptr;
|
|
||||||
Index m_rows = 0;
|
|
||||||
Index m_cols = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static constexpr int Size = Dynamic;
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl() = default;
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage_impl(const DenseStorage_impl& other)
|
|
||||||
: m_data(conditional_aligned_new_auto<T, Align>(other.size())), m_rows(other.m_rows), m_cols(other.m_cols) {
|
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = other.size())
|
|
||||||
smart_copy(other.m_data, other.m_data + other.size(), m_data);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage_impl(Index size, Index rows, Index cols)
|
|
||||||
: m_data(conditional_aligned_new_auto<T, Align>(size)), m_rows(rows), m_cols(cols) {
|
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl(DenseStorage_impl&& other) noexcept
|
|
||||||
: m_data(other.m_data), m_rows(other.m_rows), m_cols(other.m_cols) {
|
|
||||||
other.m_data = nullptr;
|
|
||||||
other.m_rows = 0;
|
|
||||||
other.m_cols = 0;
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC ~DenseStorage_impl() { conditional_aligned_delete_auto<T, Align>(m_data, size()); }
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage_impl& operator=(const DenseStorage_impl& other) {
|
|
||||||
resize(other.size(), other.rows(), other.cols());
|
|
||||||
smart_copy(other.m_data, other.m_data + other.size(), m_data);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage_impl& operator=(DenseStorage_impl&& other) noexcept {
|
|
||||||
this->swap(other);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr void swap(DenseStorage_impl& other) noexcept {
|
|
||||||
numext::swap(m_data, other.m_data);
|
|
||||||
numext::swap(m_rows, other.m_rows);
|
|
||||||
numext::swap(m_cols, other.m_cols);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void conservativeResize(Index size, Index rows, Index cols) {
|
|
||||||
m_data = conditional_aligned_realloc_new_auto<T, Align>(m_data, size, this->size());
|
|
||||||
m_rows = rows;
|
|
||||||
m_cols = cols;
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void resize(Index size, Index rows, Index cols) {
|
|
||||||
Index oldSize = this->size();
|
|
||||||
if (oldSize != size) {
|
|
||||||
conditional_aligned_delete_auto<T, Align>(m_data, oldSize);
|
|
||||||
m_data = conditional_aligned_new_auto<T, Align>(size);
|
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
|
|
||||||
}
|
|
||||||
m_rows = rows;
|
|
||||||
m_cols = cols;
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index rows() const { return m_rows; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index cols() const { return m_cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index size() const { return m_rows * m_cols; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr T* data() { return m_data; }
|
|
||||||
EIGEN_DEVICE_FUNC constexpr const T* data() const { return m_data; }
|
|
||||||
};
|
|
||||||
template <typename T, int Size, int Rows, int Cols>
|
|
||||||
struct use_default_move {
|
|
||||||
static constexpr bool DynamicObject = Size == Dynamic;
|
|
||||||
static constexpr bool TrivialObject =
|
|
||||||
(!NumTraits<T>::RequireInitialization) && (Rows >= 0) && (Cols >= 0) && (Size == Rows * Cols);
|
|
||||||
static constexpr bool value = DynamicObject || TrivialObject;
|
|
||||||
};
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
*
|
*
|
||||||
* \class DenseStorage_impl
|
* \class DenseStorage
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
*
|
*
|
||||||
* \brief Stores the data of a matrix
|
* \brief Stores the data of a matrix
|
||||||
@@ -506,41 +92,213 @@ struct use_default_move {
|
|||||||
*
|
*
|
||||||
* \sa Matrix
|
* \sa Matrix
|
||||||
*/
|
*/
|
||||||
template <typename T, int Size, int Rows, int Cols, int Options,
|
template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseStorage;
|
||||||
bool Trivial = internal::use_default_move<T, Size, Rows, Cols>::value>
|
|
||||||
class DenseStorage : public internal::DenseStorage_impl<T, Size, Rows, Cols, Options> {
|
|
||||||
using Base = internal::DenseStorage_impl<T, Size, Rows, Cols, Options>;
|
|
||||||
|
|
||||||
|
// purely fixed-size matrix
|
||||||
|
template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseStorage
|
||||||
|
{
|
||||||
|
internal::plain_array<T,Size,_Options> m_data;
|
||||||
public:
|
public:
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage() = default;
|
inline explicit DenseStorage() {}
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage(const DenseStorage&) = default;
|
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage(Index size, Index rows, Index cols) : Base(size, rows, cols) {}
|
: m_data(internal::constructor_without_unaligned_array_assert()) {}
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage& operator=(const DenseStorage&) = default;
|
inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {}
|
||||||
// if DenseStorage meets the requirements of use_default_move, then use the move construction and move assignment
|
inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); }
|
||||||
// operation defined in DenseStorage_impl, or the compiler-generated version if none is defined
|
inline static DenseIndex rows(void) {return _Rows;}
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage(DenseStorage&&) = default;
|
inline static DenseIndex cols(void) {return _Cols;}
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage& operator=(DenseStorage&&) = default;
|
inline void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {}
|
||||||
|
inline void resize(DenseIndex,DenseIndex,DenseIndex) {}
|
||||||
|
inline const T *data() const { return m_data.array; }
|
||||||
|
inline T *data() { return m_data.array; }
|
||||||
};
|
};
|
||||||
template <typename T, int Size, int Rows, int Cols, int Options>
|
|
||||||
class DenseStorage<T, Size, Rows, Cols, Options, false>
|
|
||||||
: public internal::DenseStorage_impl<T, Size, Rows, Cols, Options> {
|
|
||||||
using Base = internal::DenseStorage_impl<T, Size, Rows, Cols, Options>;
|
|
||||||
|
|
||||||
|
// null matrix
|
||||||
|
template<typename T, int _Rows, int _Cols, int _Options> class DenseStorage<T, 0, _Rows, _Cols, _Options>
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage() = default;
|
inline explicit DenseStorage() {}
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage(const DenseStorage&) = default;
|
inline DenseStorage(internal::constructor_without_unaligned_array_assert) {}
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage(Index size, Index rows, Index cols) : Base(size, rows, cols) {}
|
inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {}
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage& operator=(const DenseStorage&) = default;
|
inline void swap(DenseStorage& ) {}
|
||||||
// if DenseStorage does not meet the requirements of use_default_move, then defer to the copy construction and copy
|
inline static DenseIndex rows(void) {return _Rows;}
|
||||||
// assignment behavior
|
inline static DenseIndex cols(void) {return _Cols;}
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage(DenseStorage&& other)
|
inline void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {}
|
||||||
: DenseStorage(static_cast<const DenseStorage&>(other)) {}
|
inline void resize(DenseIndex,DenseIndex,DenseIndex) {}
|
||||||
EIGEN_DEVICE_FUNC constexpr DenseStorage& operator=(DenseStorage&& other) {
|
inline const T *data() const { return 0; }
|
||||||
*this = other;
|
inline T *data() { return 0; }
|
||||||
return *this;
|
};
|
||||||
|
|
||||||
|
// dynamic-size matrix with fixed-size storage
|
||||||
|
template<typename T, int Size, int _Options> class DenseStorage<T, Size, Dynamic, Dynamic, _Options>
|
||||||
|
{
|
||||||
|
internal::plain_array<T,Size,_Options> m_data;
|
||||||
|
DenseIndex m_rows;
|
||||||
|
DenseIndex m_cols;
|
||||||
|
public:
|
||||||
|
inline explicit DenseStorage() : m_rows(0), m_cols(0) {}
|
||||||
|
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||||
|
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {}
|
||||||
|
inline DenseStorage(DenseIndex, DenseIndex rows, DenseIndex cols) : m_rows(rows), m_cols(cols) {}
|
||||||
|
inline void swap(DenseStorage& other)
|
||||||
|
{ std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
|
||||||
|
inline DenseIndex rows(void) const {return m_rows;}
|
||||||
|
inline DenseIndex cols(void) const {return m_cols;}
|
||||||
|
inline void conservativeResize(DenseIndex, DenseIndex rows, DenseIndex cols) { m_rows = rows; m_cols = cols; }
|
||||||
|
inline void resize(DenseIndex, DenseIndex rows, DenseIndex cols) { m_rows = rows; m_cols = cols; }
|
||||||
|
inline const T *data() const { return m_data.array; }
|
||||||
|
inline T *data() { return m_data.array; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// dynamic-size matrix with fixed-size storage and fixed width
|
||||||
|
template<typename T, int Size, int _Cols, int _Options> class DenseStorage<T, Size, Dynamic, _Cols, _Options>
|
||||||
|
{
|
||||||
|
internal::plain_array<T,Size,_Options> m_data;
|
||||||
|
DenseIndex m_rows;
|
||||||
|
public:
|
||||||
|
inline explicit DenseStorage() : m_rows(0) {}
|
||||||
|
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||||
|
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {}
|
||||||
|
inline DenseStorage(DenseIndex, DenseIndex rows, DenseIndex) : m_rows(rows) {}
|
||||||
|
inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
|
||||||
|
inline DenseIndex rows(void) const {return m_rows;}
|
||||||
|
inline DenseIndex cols(void) const {return _Cols;}
|
||||||
|
inline void conservativeResize(DenseIndex, DenseIndex rows, DenseIndex) { m_rows = rows; }
|
||||||
|
inline void resize(DenseIndex, DenseIndex rows, DenseIndex) { m_rows = rows; }
|
||||||
|
inline const T *data() const { return m_data.array; }
|
||||||
|
inline T *data() { return m_data.array; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// dynamic-size matrix with fixed-size storage and fixed height
|
||||||
|
template<typename T, int Size, int _Rows, int _Options> class DenseStorage<T, Size, _Rows, Dynamic, _Options>
|
||||||
|
{
|
||||||
|
internal::plain_array<T,Size,_Options> m_data;
|
||||||
|
DenseIndex m_cols;
|
||||||
|
public:
|
||||||
|
inline explicit DenseStorage() : m_cols(0) {}
|
||||||
|
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||||
|
: m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {}
|
||||||
|
inline DenseStorage(DenseIndex, DenseIndex, DenseIndex cols) : m_cols(cols) {}
|
||||||
|
inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
|
||||||
|
inline DenseIndex rows(void) const {return _Rows;}
|
||||||
|
inline DenseIndex cols(void) const {return m_cols;}
|
||||||
|
inline void conservativeResize(DenseIndex, DenseIndex, DenseIndex cols) { m_cols = cols; }
|
||||||
|
inline void resize(DenseIndex, DenseIndex, DenseIndex cols) { m_cols = cols; }
|
||||||
|
inline const T *data() const { return m_data.array; }
|
||||||
|
inline T *data() { return m_data.array; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// purely dynamic matrix.
|
||||||
|
template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynamic, _Options>
|
||||||
|
{
|
||||||
|
T *m_data;
|
||||||
|
DenseIndex m_rows;
|
||||||
|
DenseIndex m_cols;
|
||||||
|
public:
|
||||||
|
inline explicit DenseStorage() : m_data(0), m_rows(0), m_cols(0) {}
|
||||||
|
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||||
|
: m_data(0), m_rows(0), m_cols(0) {}
|
||||||
|
inline DenseStorage(DenseIndex size, DenseIndex rows, DenseIndex cols)
|
||||||
|
: m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(rows), m_cols(cols)
|
||||||
|
{ EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN }
|
||||||
|
inline ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols); }
|
||||||
|
inline void swap(DenseStorage& other)
|
||||||
|
{ std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
|
||||||
|
inline DenseIndex rows(void) const {return m_rows;}
|
||||||
|
inline DenseIndex cols(void) const {return m_cols;}
|
||||||
|
inline void conservativeResize(DenseIndex size, DenseIndex rows, DenseIndex cols)
|
||||||
|
{
|
||||||
|
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*m_cols);
|
||||||
|
m_rows = rows;
|
||||||
|
m_cols = cols;
|
||||||
}
|
}
|
||||||
|
void resize(DenseIndex size, DenseIndex rows, DenseIndex cols)
|
||||||
|
{
|
||||||
|
if(size != m_rows*m_cols)
|
||||||
|
{
|
||||||
|
internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols);
|
||||||
|
if (size)
|
||||||
|
m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
|
||||||
|
else
|
||||||
|
m_data = 0;
|
||||||
|
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
|
||||||
|
}
|
||||||
|
m_rows = rows;
|
||||||
|
m_cols = cols;
|
||||||
|
}
|
||||||
|
inline const T *data() const { return m_data; }
|
||||||
|
inline T *data() { return m_data; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace Eigen
|
// matrix with dynamic width and fixed height (so that matrix has dynamic size).
|
||||||
|
template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Rows, Dynamic, _Options>
|
||||||
|
{
|
||||||
|
T *m_data;
|
||||||
|
DenseIndex m_cols;
|
||||||
|
public:
|
||||||
|
inline explicit DenseStorage() : m_data(0), m_cols(0) {}
|
||||||
|
inline DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {}
|
||||||
|
inline DenseStorage(DenseIndex size, DenseIndex, DenseIndex cols) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_cols(cols)
|
||||||
|
{ EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN }
|
||||||
|
inline ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); }
|
||||||
|
inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
|
||||||
|
inline static DenseIndex rows(void) {return _Rows;}
|
||||||
|
inline DenseIndex cols(void) const {return m_cols;}
|
||||||
|
inline void conservativeResize(DenseIndex size, DenseIndex, DenseIndex cols)
|
||||||
|
{
|
||||||
|
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, _Rows*m_cols);
|
||||||
|
m_cols = cols;
|
||||||
|
}
|
||||||
|
EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex, DenseIndex cols)
|
||||||
|
{
|
||||||
|
if(size != _Rows*m_cols)
|
||||||
|
{
|
||||||
|
internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols);
|
||||||
|
if (size)
|
||||||
|
m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
|
||||||
|
else
|
||||||
|
m_data = 0;
|
||||||
|
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
|
||||||
|
}
|
||||||
|
m_cols = cols;
|
||||||
|
}
|
||||||
|
inline const T *data() const { return m_data; }
|
||||||
|
inline T *data() { return m_data; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// matrix with dynamic height and fixed width (so that matrix has dynamic size).
|
||||||
|
template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dynamic, _Cols, _Options>
|
||||||
|
{
|
||||||
|
T *m_data;
|
||||||
|
DenseIndex m_rows;
|
||||||
|
public:
|
||||||
|
inline explicit DenseStorage() : m_data(0), m_rows(0) {}
|
||||||
|
inline DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {}
|
||||||
|
inline DenseStorage(DenseIndex size, DenseIndex rows, DenseIndex) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(rows)
|
||||||
|
{ EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN }
|
||||||
|
inline ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); }
|
||||||
|
inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
|
||||||
|
inline DenseIndex rows(void) const {return m_rows;}
|
||||||
|
inline static DenseIndex cols(void) {return _Cols;}
|
||||||
|
inline void conservativeResize(DenseIndex size, DenseIndex rows, DenseIndex)
|
||||||
|
{
|
||||||
|
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*_Cols);
|
||||||
|
m_rows = rows;
|
||||||
|
}
|
||||||
|
EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex rows, DenseIndex)
|
||||||
|
{
|
||||||
|
if(size != m_rows*_Cols)
|
||||||
|
{
|
||||||
|
internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows);
|
||||||
|
if (size)
|
||||||
|
m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
|
||||||
|
else
|
||||||
|
m_data = 0;
|
||||||
|
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
|
||||||
|
}
|
||||||
|
m_rows = rows;
|
||||||
|
}
|
||||||
|
inline const T *data() const { return m_data; }
|
||||||
|
inline T *data() { return m_data; }
|
||||||
|
};
|
||||||
|
|
||||||
#endif // EIGEN_MATRIX_H
|
#endif // EIGEN_MATRIX_H
|
||||||
|
|||||||
@@ -1,153 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2023 Charlie Schlosser <cs.schlosser@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_DEVICEWRAPPER_H
|
|
||||||
#define EIGEN_DEVICEWRAPPER_H
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
template <typename Derived, typename Device>
|
|
||||||
struct DeviceWrapper {
|
|
||||||
using Base = EigenBase<internal::remove_all_t<Derived>>;
|
|
||||||
using Scalar = typename Derived::Scalar;
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC DeviceWrapper(Base& xpr, Device& device) : m_xpr(xpr.derived()), m_device(device) {}
|
|
||||||
EIGEN_DEVICE_FUNC DeviceWrapper(const Base& xpr, Device& device) : m_xpr(xpr.derived()), m_device(device) {}
|
|
||||||
|
|
||||||
template <typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived>& other) {
|
|
||||||
using AssignOp = internal::assign_op<Scalar, typename OtherDerived::Scalar>;
|
|
||||||
internal::call_assignment(*this, other.derived(), AssignOp());
|
|
||||||
return m_xpr;
|
|
||||||
}
|
|
||||||
template <typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator+=(const EigenBase<OtherDerived>& other) {
|
|
||||||
using AddAssignOp = internal::add_assign_op<Scalar, typename OtherDerived::Scalar>;
|
|
||||||
internal::call_assignment(*this, other.derived(), AddAssignOp());
|
|
||||||
return m_xpr;
|
|
||||||
}
|
|
||||||
template <typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator-=(const EigenBase<OtherDerived>& other) {
|
|
||||||
using SubAssignOp = internal::sub_assign_op<Scalar, typename OtherDerived::Scalar>;
|
|
||||||
internal::call_assignment(*this, other.derived(), SubAssignOp());
|
|
||||||
return m_xpr;
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& derived() { return m_xpr; }
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Device& device() { return m_device; }
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE NoAlias<DeviceWrapper, EigenBase> noalias() {
|
|
||||||
return NoAlias<DeviceWrapper, EigenBase>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
Derived& m_xpr;
|
|
||||||
Device& m_device;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
// this is where we differentiate between lazy assignment and specialized kernels (e.g. matrix products)
|
|
||||||
template <typename DstXprType, typename SrcXprType, typename Functor, typename Device,
|
|
||||||
typename Kind = typename AssignmentKind<typename evaluator_traits<DstXprType>::Shape,
|
|
||||||
typename evaluator_traits<SrcXprType>::Shape>::Kind,
|
|
||||||
typename EnableIf = void>
|
|
||||||
struct AssignmentWithDevice;
|
|
||||||
|
|
||||||
// unless otherwise specified, use the default product implementation
|
|
||||||
template <typename DstXprType, typename Lhs, typename Rhs, int Options, typename Functor, typename Device,
|
|
||||||
typename Weak>
|
|
||||||
struct AssignmentWithDevice<DstXprType, Product<Lhs, Rhs, Options>, Functor, Device, Dense2Dense, Weak> {
|
|
||||||
using SrcXprType = Product<Lhs, Rhs, Options>;
|
|
||||||
using Base = Assignment<DstXprType, SrcXprType, Functor>;
|
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(DstXprType& dst, const SrcXprType& src, const Functor& func,
|
|
||||||
Device&) {
|
|
||||||
Base::run(dst, src, func);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// specialization for coeffcient-wise assignment
|
|
||||||
template <typename DstXprType, typename SrcXprType, typename Functor, typename Device, typename Weak>
|
|
||||||
struct AssignmentWithDevice<DstXprType, SrcXprType, Functor, Device, Dense2Dense, Weak> {
|
|
||||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(DstXprType& dst, const SrcXprType& src, const Functor& func,
|
|
||||||
Device& device) {
|
|
||||||
#ifndef EIGEN_NO_DEBUG
|
|
||||||
internal::check_for_aliasing(dst, src);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
call_dense_assignment_loop(dst, src, func, device);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// this allows us to use the default evaluation scheme if it is not specialized for the device
|
|
||||||
template <typename Kernel, typename Device, int Traversal = Kernel::AssignmentTraits::Traversal,
|
|
||||||
int Unrolling = Kernel::AssignmentTraits::Unrolling>
|
|
||||||
struct dense_assignment_loop_with_device {
|
|
||||||
using Base = dense_assignment_loop<Kernel, Traversal, Unrolling>;
|
|
||||||
static EIGEN_DEVICE_FUNC constexpr void run(Kernel& kernel, Device&) { Base::run(kernel); }
|
|
||||||
};
|
|
||||||
|
|
||||||
// entry point for a generic expression with device
|
|
||||||
template <typename Dst, typename Src, typename Func, typename Device>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void call_assignment_no_alias(DeviceWrapper<Dst, Device> dst,
|
|
||||||
const Src& src, const Func& func) {
|
|
||||||
enum {
|
|
||||||
NeedToTranspose = ((int(Dst::RowsAtCompileTime) == 1 && int(Src::ColsAtCompileTime) == 1) ||
|
|
||||||
(int(Dst::ColsAtCompileTime) == 1 && int(Src::RowsAtCompileTime) == 1)) &&
|
|
||||||
int(Dst::SizeAtCompileTime) != 1
|
|
||||||
};
|
|
||||||
|
|
||||||
using ActualDstTypeCleaned = std::conditional_t<NeedToTranspose, Transpose<Dst>, Dst>;
|
|
||||||
using ActualDstType = std::conditional_t<NeedToTranspose, Transpose<Dst>, Dst&>;
|
|
||||||
ActualDstType actualDst(dst.derived());
|
|
||||||
|
|
||||||
// TODO: check whether this is the right place to perform these checks:
|
|
||||||
EIGEN_STATIC_ASSERT_LVALUE(Dst)
|
|
||||||
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(ActualDstTypeCleaned, Src)
|
|
||||||
EIGEN_CHECK_BINARY_COMPATIBILIY(Func, typename ActualDstTypeCleaned::Scalar, typename Src::Scalar);
|
|
||||||
|
|
||||||
// this provides a mechanism for specializing simple assignments, matrix products, etc
|
|
||||||
AssignmentWithDevice<ActualDstTypeCleaned, Src, Func, Device>::run(actualDst, src, func, dst.device());
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy and pasted from AssignEvaluator except forward device to kernel
|
|
||||||
template <typename DstXprType, typename SrcXprType, typename Functor, typename Device>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void call_dense_assignment_loop(DstXprType& dst, const SrcXprType& src,
|
|
||||||
const Functor& func, Device& device) {
|
|
||||||
using DstEvaluatorType = evaluator<DstXprType>;
|
|
||||||
using SrcEvaluatorType = evaluator<SrcXprType>;
|
|
||||||
|
|
||||||
SrcEvaluatorType srcEvaluator(src);
|
|
||||||
|
|
||||||
// NOTE To properly handle A = (A*A.transpose())/s with A rectangular,
|
|
||||||
// we need to resize the destination after the source evaluator has been created.
|
|
||||||
resize_if_allowed(dst, src, func);
|
|
||||||
|
|
||||||
DstEvaluatorType dstEvaluator(dst);
|
|
||||||
|
|
||||||
using Kernel = generic_dense_assignment_kernel<DstEvaluatorType, SrcEvaluatorType, Functor>;
|
|
||||||
|
|
||||||
Kernel kernel(dstEvaluator, srcEvaluator, func, dst.const_cast_derived());
|
|
||||||
|
|
||||||
dense_assignment_loop_with_device<Kernel, Device>::run(kernel, device);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
template <typename Derived>
|
|
||||||
template <typename Device>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DeviceWrapper<Derived, Device> EigenBase<Derived>::device(Device& device) {
|
|
||||||
return DeviceWrapper<Derived, Device>(derived(), device);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Derived>
|
|
||||||
template <typename Device>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DeviceWrapper<const Derived, Device> EigenBase<Derived>::device(
|
|
||||||
Device& device) const {
|
|
||||||
return DeviceWrapper<const Derived, Device>(derived(), device);
|
|
||||||
}
|
|
||||||
} // namespace Eigen
|
|
||||||
#endif
|
|
||||||
@@ -2,29 +2,38 @@
|
|||||||
// for linear algebra.
|
// for linear algebra.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
|
// Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||||
// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
|
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_DIAGONAL_H
|
#ifndef EIGEN_DIAGONAL_H
|
||||||
#define EIGEN_DIAGONAL_H
|
#define EIGEN_DIAGONAL_H
|
||||||
|
|
||||||
// IWYU pragma: private
|
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
/** \class Diagonal
|
/** \class Diagonal
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
*
|
*
|
||||||
* \brief Expression of a diagonal/subdiagonal/superdiagonal in a matrix
|
* \brief Expression of a diagonal/subdiagonal/superdiagonal in a matrix
|
||||||
*
|
*
|
||||||
* \tparam MatrixType the type of the object in which we are taking a sub/main/super diagonal
|
* \param MatrixType the type of the object in which we are taking a sub/main/super diagonal
|
||||||
* \tparam DiagIndex the index of the sub/super diagonal. The default is 0 and it means the main diagonal.
|
* \param DiagIndex the index of the sub/super diagonal. The default is 0 and it means the main diagonal.
|
||||||
* A positive value means a superdiagonal, a negative value means a subdiagonal.
|
* A positive value means a superdiagonal, a negative value means a subdiagonal.
|
||||||
* You can also use DynamicIndex so the index can be set at runtime.
|
* You can also use Dynamic so the index can be set at runtime.
|
||||||
*
|
*
|
||||||
* The matrix is not required to be square.
|
* The matrix is not required to be square.
|
||||||
*
|
*
|
||||||
@@ -37,116 +46,105 @@ namespace Eigen {
|
|||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
template<typename MatrixType, int DiagIndex>
|
template<typename MatrixType, int DiagIndex>
|
||||||
struct traits<Diagonal<MatrixType, DiagIndex> > : traits<MatrixType> {
|
struct traits<Diagonal<MatrixType,DiagIndex> >
|
||||||
typedef typename ref_selector<MatrixType>::type MatrixTypeNested;
|
: traits<MatrixType>
|
||||||
typedef std::remove_reference_t<MatrixTypeNested> MatrixTypeNested_;
|
{
|
||||||
|
typedef typename nested<MatrixType>::type MatrixTypeNested;
|
||||||
|
typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested;
|
||||||
typedef typename MatrixType::StorageKind StorageKind;
|
typedef typename MatrixType::StorageKind StorageKind;
|
||||||
enum {
|
enum {
|
||||||
RowsAtCompileTime = (int(DiagIndex) == DynamicIndex || int(MatrixType::SizeAtCompileTime) == Dynamic)
|
AbsDiagIndex = DiagIndex<0 ? -DiagIndex : DiagIndex, // only used if DiagIndex != Dynamic
|
||||||
? Dynamic
|
// FIXME these computations are broken in the case where the matrix is rectangular and DiagIndex!=0
|
||||||
: (plain_enum_min(MatrixType::RowsAtCompileTime - plain_enum_max(-DiagIndex, 0),
|
RowsAtCompileTime = (int(DiagIndex) == Dynamic || int(MatrixType::SizeAtCompileTime) == Dynamic) ? Dynamic
|
||||||
MatrixType::ColsAtCompileTime - plain_enum_max(DiagIndex, 0))),
|
: (EIGEN_SIZE_MIN_PREFER_DYNAMIC(MatrixType::RowsAtCompileTime,
|
||||||
|
MatrixType::ColsAtCompileTime) - AbsDiagIndex),
|
||||||
ColsAtCompileTime = 1,
|
ColsAtCompileTime = 1,
|
||||||
MaxRowsAtCompileTime =
|
MaxRowsAtCompileTime = int(MatrixType::MaxSizeAtCompileTime) == Dynamic ? Dynamic
|
||||||
int(MatrixType::MaxSizeAtCompileTime) == Dynamic ? Dynamic
|
: DiagIndex == Dynamic ? EIGEN_SIZE_MIN_PREFER_FIXED(MatrixType::MaxRowsAtCompileTime,
|
||||||
: DiagIndex == DynamicIndex
|
MatrixType::MaxColsAtCompileTime)
|
||||||
? min_size_prefer_fixed(MatrixType::MaxRowsAtCompileTime, MatrixType::MaxColsAtCompileTime)
|
: (EIGEN_SIZE_MIN_PREFER_FIXED(MatrixType::MaxRowsAtCompileTime, MatrixType::MaxColsAtCompileTime) - AbsDiagIndex),
|
||||||
: (plain_enum_min(MatrixType::MaxRowsAtCompileTime - plain_enum_max(-DiagIndex, 0),
|
|
||||||
MatrixType::MaxColsAtCompileTime - plain_enum_max(DiagIndex, 0))),
|
|
||||||
MaxColsAtCompileTime = 1,
|
MaxColsAtCompileTime = 1,
|
||||||
MaskLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
|
MaskLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
|
||||||
Flags = (unsigned int)MatrixTypeNested_::Flags & (RowMajorBit | MaskLvalueBit | DirectAccessBit) &
|
Flags = (unsigned int)_MatrixTypeNested::Flags & (HereditaryBits | LinearAccessBit | MaskLvalueBit | DirectAccessBit) & ~RowMajorBit,
|
||||||
~RowMajorBit, // FIXME DirectAccessBit should not be handled by expressions
|
CoeffReadCost = _MatrixTypeNested::CoeffReadCost,
|
||||||
MatrixTypeOuterStride = outer_stride_at_compile_time<MatrixType>::ret,
|
MatrixTypeOuterStride = outer_stride_at_compile_time<MatrixType>::ret,
|
||||||
InnerStrideAtCompileTime = MatrixTypeOuterStride == Dynamic ? Dynamic : MatrixTypeOuterStride+1,
|
InnerStrideAtCompileTime = MatrixTypeOuterStride == Dynamic ? Dynamic : MatrixTypeOuterStride+1,
|
||||||
OuterStrideAtCompileTime = 0
|
OuterStrideAtCompileTime = 0
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} // namespace internal
|
}
|
||||||
|
|
||||||
template <typename MatrixType, int DiagIndex_>
|
template<typename MatrixType, int DiagIndex> class Diagonal
|
||||||
class Diagonal : public internal::dense_xpr_base<Diagonal<MatrixType, DiagIndex_> >::type {
|
: public internal::dense_xpr_base< Diagonal<MatrixType,DiagIndex> >::type
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
enum { DiagIndex = DiagIndex_ };
|
|
||||||
typedef typename internal::dense_xpr_base<Diagonal>::type Base;
|
typedef typename internal::dense_xpr_base<Diagonal>::type Base;
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE(Diagonal)
|
EIGEN_DENSE_PUBLIC_INTERFACE(Diagonal)
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr explicit inline Diagonal(MatrixType& matrix, Index a_index = DiagIndex)
|
inline Diagonal(MatrixType& matrix, Index index = DiagIndex) : m_matrix(matrix), m_index(index) {}
|
||||||
: m_matrix(matrix), m_index(a_index) {
|
|
||||||
eigen_assert(a_index <= m_matrix.cols() && -a_index <= m_matrix.rows());
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Diagonal)
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Diagonal)
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr inline Index rows() const {
|
inline Index rows() const
|
||||||
return m_index.value() < 0 ? numext::mini<Index>(m_matrix.cols(), m_matrix.rows() + m_index.value())
|
{ return m_index.value()<0 ? (std::min)(m_matrix.cols(),m_matrix.rows()+m_index.value()) : (std::min)(m_matrix.rows(),m_matrix.cols()-m_index.value()); }
|
||||||
: numext::mini<Index>(m_matrix.rows(), m_matrix.cols() - m_index.value());
|
|
||||||
|
inline Index cols() const { return 1; }
|
||||||
|
|
||||||
|
inline Index innerStride() const
|
||||||
|
{
|
||||||
|
return m_matrix.outerStride() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index cols() const noexcept { return 1; }
|
inline Index outerStride() const
|
||||||
|
{
|
||||||
EIGEN_DEVICE_FUNC constexpr Index innerStride() const noexcept { return m_matrix.outerStride() + 1; }
|
return 0;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index outerStride() const noexcept { return 0; }
|
|
||||||
|
|
||||||
typedef std::conditional_t<internal::is_lvalue<MatrixType>::value, Scalar, const Scalar> ScalarWithConstIfNotLvalue;
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline ScalarWithConstIfNotLvalue* data() {
|
|
||||||
return rows() > 0 ? &(m_matrix.coeffRef(rowOffset(), colOffset())) : nullptr;
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC inline const Scalar* data() const {
|
|
||||||
return rows() > 0 ? &(m_matrix.coeffRef(rowOffset(), colOffset())) : nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index row, Index) {
|
inline Scalar& coeffRef(Index row, Index)
|
||||||
|
{
|
||||||
EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
|
EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
|
||||||
return m_matrix.coeffRef(row + rowOffset(), row + colOffset());
|
return m_matrix.const_cast_derived().coeffRef(row+rowOffset(), row+colOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline const Scalar& coeffRef(Index row, Index) const {
|
inline const Scalar& coeffRef(Index row, Index) const
|
||||||
return m_matrix.coeffRef(row + rowOffset(), row + colOffset());
|
{
|
||||||
|
return m_matrix.const_cast_derived().coeffRef(row+rowOffset(), row+colOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline CoeffReturnType coeff(Index row, Index) const {
|
inline CoeffReturnType coeff(Index row, Index) const
|
||||||
|
{
|
||||||
return m_matrix.coeff(row+rowOffset(), row+colOffset());
|
return m_matrix.coeff(row+rowOffset(), row+colOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index idx) {
|
inline Scalar& coeffRef(Index index)
|
||||||
|
{
|
||||||
EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
|
EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
|
||||||
return m_matrix.coeffRef(idx + rowOffset(), idx + colOffset());
|
return m_matrix.const_cast_derived().coeffRef(index+rowOffset(), index+colOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline const Scalar& coeffRef(Index idx) const {
|
inline const Scalar& coeffRef(Index index) const
|
||||||
return m_matrix.coeffRef(idx + rowOffset(), idx + colOffset());
|
{
|
||||||
|
return m_matrix.const_cast_derived().coeffRef(index+rowOffset(), index+colOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline CoeffReturnType coeff(Index idx) const {
|
inline CoeffReturnType coeff(Index index) const
|
||||||
return m_matrix.coeff(idx + rowOffset(), idx + colOffset());
|
{
|
||||||
|
return m_matrix.coeff(index+rowOffset(), index+colOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr inline const internal::remove_all_t<typename MatrixType::Nested>& nestedExpression()
|
|
||||||
const {
|
|
||||||
return m_matrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC constexpr inline Index index() const { return m_index.value(); }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typename internal::ref_selector<MatrixType>::non_const_type m_matrix;
|
const typename MatrixType::Nested m_matrix;
|
||||||
const internal::variable_if_dynamicindex<Index, DiagIndex> m_index;
|
const internal::variable_if_dynamic<Index, DiagIndex> m_index;
|
||||||
|
|
||||||
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 constexpr Index absDiagIndex() const noexcept {
|
EIGEN_STRONG_INLINE Index absDiagIndex() const { return m_index.value()>0 ? m_index.value() : -m_index.value(); }
|
||||||
return m_index.value() > 0 ? m_index.value() : -m_index.value();
|
EIGEN_STRONG_INLINE Index rowOffset() const { return m_index.value()>0 ? 0 : -m_index.value(); }
|
||||||
}
|
EIGEN_STRONG_INLINE Index colOffset() const { return m_index.value()>0 ? m_index.value() : 0; }
|
||||||
EIGEN_DEVICE_FUNC constexpr Index rowOffset() const noexcept { return m_index.value() > 0 ? 0 : -m_index.value(); }
|
// triger a compile time error is someone try to call packet
|
||||||
EIGEN_DEVICE_FUNC constexpr Index colOffset() const noexcept { return m_index.value() > 0 ? m_index.value() : 0; }
|
template<int LoadMode> typename MatrixType::PacketReturnType packet(Index) const;
|
||||||
// trigger a compile-time error if someone try to call packet
|
template<int LoadMode> typename MatrixType::PacketReturnType packet(Index,Index) const;
|
||||||
template <int LoadMode>
|
|
||||||
typename MatrixType::PacketReturnType packet(Index) const;
|
|
||||||
template <int LoadMode>
|
|
||||||
typename MatrixType::PacketReturnType packet(Index, Index) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \returns an expression of the main diagonal of the matrix \c *this
|
/** \returns an expression of the main diagonal of the matrix \c *this
|
||||||
@@ -158,14 +156,17 @@ class Diagonal : public internal::dense_xpr_base<Diagonal<MatrixType, DiagIndex_
|
|||||||
*
|
*
|
||||||
* \sa class Diagonal */
|
* \sa class Diagonal */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC constexpr typename MatrixBase<Derived>::DiagonalReturnType MatrixBase<Derived>::diagonal() {
|
inline typename MatrixBase<Derived>::DiagonalReturnType
|
||||||
return DiagonalReturnType(derived());
|
MatrixBase<Derived>::diagonal()
|
||||||
|
{
|
||||||
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This is the const version of diagonal(). */
|
/** This is the const version of diagonal(). */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC constexpr const typename MatrixBase<Derived>::ConstDiagonalReturnType MatrixBase<Derived>::diagonal()
|
inline const typename MatrixBase<Derived>::ConstDiagonalReturnType
|
||||||
const {
|
MatrixBase<Derived>::diagonal() const
|
||||||
|
{
|
||||||
return ConstDiagonalReturnType(derived());
|
return ConstDiagonalReturnType(derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,15 +182,18 @@ EIGEN_DEVICE_FUNC constexpr const typename MatrixBase<Derived>::ConstDiagonalRet
|
|||||||
*
|
*
|
||||||
* \sa MatrixBase::diagonal(), class Diagonal */
|
* \sa MatrixBase::diagonal(), class Diagonal */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC constexpr Diagonal<Derived, DynamicIndex> MatrixBase<Derived>::diagonal(Index index) {
|
inline typename MatrixBase<Derived>::template DiagonalIndexReturnType<Dynamic>::Type
|
||||||
return Diagonal<Derived, DynamicIndex>(derived(), index);
|
MatrixBase<Derived>::diagonal(Index index)
|
||||||
|
{
|
||||||
|
return typename DiagonalIndexReturnType<Dynamic>::Type(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 constexpr const Diagonal<const Derived, DynamicIndex> MatrixBase<Derived>::diagonal(
|
inline typename MatrixBase<Derived>::template ConstDiagonalIndexReturnType<Dynamic>::Type
|
||||||
Index index) const {
|
MatrixBase<Derived>::diagonal(Index index) const
|
||||||
return Diagonal<const Derived, DynamicIndex>(derived(), index);
|
{
|
||||||
|
return typename ConstDiagonalIndexReturnType<Dynamic>::Type(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
|
||||||
@@ -204,18 +208,20 @@ EIGEN_DEVICE_FUNC constexpr const Diagonal<const Derived, DynamicIndex> MatrixBa
|
|||||||
*
|
*
|
||||||
* \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 constexpr Diagonal<Derived, Index_> MatrixBase<Derived>::diagonal() {
|
inline typename MatrixBase<Derived>::template DiagonalIndexReturnType<Index>::Type
|
||||||
return Diagonal<Derived, Index_>(derived());
|
MatrixBase<Derived>::diagonal()
|
||||||
|
{
|
||||||
|
return 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 constexpr const Diagonal<const Derived, Index_> MatrixBase<Derived>::diagonal() const {
|
inline typename MatrixBase<Derived>::template ConstDiagonalIndexReturnType<Index>::Type
|
||||||
return Diagonal<const Derived, Index_>(derived());
|
MatrixBase<Derived>::diagonal() const
|
||||||
|
{
|
||||||
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_DIAGONAL_H
|
#endif // EIGEN_DIAGONAL_H
|
||||||
|
|||||||
@@ -4,39 +4,37 @@
|
|||||||
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
// Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
|
// Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_DIAGONALMATRIX_H
|
#ifndef EIGEN_DIAGONALMATRIX_H
|
||||||
#define EIGEN_DIAGONALMATRIX_H
|
#define EIGEN_DIAGONALMATRIX_H
|
||||||
|
|
||||||
// IWYU pragma: private
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
/** \class DiagonalBase
|
|
||||||
* \ingroup Core_Module
|
|
||||||
*
|
|
||||||
* \brief Base class for diagonal matrices and expressions
|
|
||||||
*
|
|
||||||
* This is the base class that is inherited by diagonal matrix and related expression
|
|
||||||
* types, which internally use a vector for storing the diagonal entries. Diagonal
|
|
||||||
* types always represent square matrices.
|
|
||||||
*
|
|
||||||
* \tparam Derived is the derived type, a DiagonalMatrix or DiagonalWrapper.
|
|
||||||
*
|
|
||||||
* \sa class DiagonalMatrix, class DiagonalWrapper
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
class DiagonalBase : public EigenBase<Derived> {
|
class DiagonalBase : public EigenBase<Derived>
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename internal::traits<Derived>::DiagonalVectorType DiagonalVectorType;
|
typedef typename internal::traits<Derived>::DiagonalVectorType DiagonalVectorType;
|
||||||
typedef typename DiagonalVectorType::Scalar Scalar;
|
typedef typename DiagonalVectorType::Scalar Scalar;
|
||||||
typedef typename DiagonalVectorType::RealScalar RealScalar;
|
|
||||||
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
||||||
typedef typename internal::traits<Derived>::StorageIndex StorageIndex;
|
typedef typename internal::traits<Derived>::Index Index;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
|
RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
|
||||||
@@ -44,190 +42,130 @@ class DiagonalBase : public EigenBase<Derived> {
|
|||||||
MaxRowsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
|
MaxRowsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
|
||||||
MaxColsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
|
MaxColsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
|
||||||
IsVectorAtCompileTime = 0,
|
IsVectorAtCompileTime = 0,
|
||||||
Flags = NoPreferredStorageOrderBit
|
Flags = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime, 0, MaxRowsAtCompileTime, MaxColsAtCompileTime>
|
typedef Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime, 0, MaxRowsAtCompileTime, MaxColsAtCompileTime> DenseMatrixType;
|
||||||
DenseMatrixType;
|
|
||||||
typedef DenseMatrixType DenseType;
|
typedef DenseMatrixType DenseType;
|
||||||
typedef DiagonalMatrix<Scalar, DiagonalVectorType::SizeAtCompileTime, DiagonalVectorType::MaxSizeAtCompileTime>
|
typedef DiagonalMatrix<Scalar,DiagonalVectorType::SizeAtCompileTime,DiagonalVectorType::MaxSizeAtCompileTime> PlainObject;
|
||||||
PlainObject;
|
|
||||||
|
|
||||||
/** \returns a reference to the derived object. */
|
inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
|
||||||
EIGEN_DEVICE_FUNC inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
|
inline Derived& derived() { return *static_cast<Derived*>(this); }
|
||||||
/** \returns a const reference to the derived object. */
|
|
||||||
EIGEN_DEVICE_FUNC inline Derived& derived() { return *static_cast<Derived*>(this); }
|
|
||||||
|
|
||||||
/**
|
DenseMatrixType toDenseMatrix() const { return derived(); }
|
||||||
* Constructs a dense matrix from \c *this. Note, this directly returns a dense matrix type,
|
template<typename DenseDerived>
|
||||||
* not an expression.
|
void evalTo(MatrixBase<DenseDerived> &other) const;
|
||||||
* \returns A dense matrix, with its diagonal entries set from the derived object. */
|
template<typename DenseDerived>
|
||||||
EIGEN_DEVICE_FUNC DenseMatrixType toDenseMatrix() const { return derived(); }
|
void addTo(MatrixBase<DenseDerived> &other) const
|
||||||
|
{ other.diagonal() += diagonal(); }
|
||||||
|
template<typename DenseDerived>
|
||||||
|
void subTo(MatrixBase<DenseDerived> &other) const
|
||||||
|
{ other.diagonal() -= diagonal(); }
|
||||||
|
|
||||||
/** \returns a reference to the derived object's vector of diagonal coefficients. */
|
inline const DiagonalVectorType& diagonal() const { return derived().diagonal(); }
|
||||||
EIGEN_DEVICE_FUNC inline const DiagonalVectorType& diagonal() const { return derived().diagonal(); }
|
inline DiagonalVectorType& diagonal() { return derived().diagonal(); }
|
||||||
/** \returns a const reference to the derived object's vector of diagonal coefficients. */
|
|
||||||
EIGEN_DEVICE_FUNC inline DiagonalVectorType& diagonal() { return derived().diagonal(); }
|
|
||||||
|
|
||||||
/** \returns the value of the coefficient as if \c *this was a dense matrix. */
|
inline Index rows() const { return diagonal().size(); }
|
||||||
EIGEN_DEVICE_FUNC inline Scalar coeff(Index row, Index col) const {
|
inline Index cols() const { return diagonal().size(); }
|
||||||
eigen_assert(row >= 0 && col >= 0 && row < rows() && col <= cols());
|
|
||||||
return row == col ? diagonal().coeff(row) : Scalar(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \returns the number of rows. */
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index rows() const { return diagonal().size(); }
|
|
||||||
/** \returns the number of columns. */
|
|
||||||
EIGEN_DEVICE_FUNC constexpr Index cols() const { return diagonal().size(); }
|
|
||||||
|
|
||||||
/** \returns the diagonal matrix product of \c *this by the dense matrix, \a matrix */
|
|
||||||
template<typename MatrixDerived>
|
template<typename MatrixDerived>
|
||||||
EIGEN_DEVICE_FUNC const Product<Derived, MatrixDerived, LazyProduct> operator*(
|
const DiagonalProduct<MatrixDerived, Derived, OnTheLeft>
|
||||||
const MatrixBase<MatrixDerived>& matrix) const {
|
operator*(const MatrixBase<MatrixDerived> &matrix) const;
|
||||||
return Product<Derived, MatrixDerived, LazyProduct>(derived(), matrix.derived());
|
|
||||||
|
inline const DiagonalWrapper<CwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const DiagonalVectorType> >
|
||||||
|
inverse() const
|
||||||
|
{
|
||||||
|
return diagonal().cwiseInverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef EIGEN2_SUPPORT
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
using DiagonalProductReturnType = DiagonalWrapper<const EIGEN_CWISE_BINARY_RETURN_TYPE(
|
bool isApprox(const DiagonalBase<OtherDerived>& other, typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision()) const
|
||||||
DiagonalVectorType, typename OtherDerived::DiagonalVectorType, product)>;
|
{
|
||||||
|
return diagonal().isApprox(other.diagonal(), precision);
|
||||||
/** \returns the diagonal matrix product of \c *this by the diagonal matrix \a other */
|
}
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC const DiagonalProductReturnType<OtherDerived> operator*(
|
bool isApprox(const MatrixBase<OtherDerived>& other, typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision()) const
|
||||||
const DiagonalBase<OtherDerived>& other) const {
|
{
|
||||||
return diagonal().cwiseProduct(other.diagonal()).asDiagonal();
|
return toDenseMatrix().isApprox(other, precision);
|
||||||
}
|
|
||||||
|
|
||||||
using DiagonalInverseReturnType =
|
|
||||||
DiagonalWrapper<const CwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const DiagonalVectorType>>;
|
|
||||||
|
|
||||||
/** \returns the inverse \c *this. Computed as the coefficient-wise inverse of the diagonal. */
|
|
||||||
EIGEN_DEVICE_FUNC inline const DiagonalInverseReturnType inverse() const {
|
|
||||||
return diagonal().cwiseInverse().asDiagonal();
|
|
||||||
}
|
|
||||||
|
|
||||||
using DiagonalScaleReturnType =
|
|
||||||
DiagonalWrapper<const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DiagonalVectorType, Scalar, product)>;
|
|
||||||
|
|
||||||
/** \returns the product of \c *this by the scalar \a scalar */
|
|
||||||
EIGEN_DEVICE_FUNC inline const DiagonalScaleReturnType operator*(const Scalar& scalar) const {
|
|
||||||
return (diagonal() * scalar).asDiagonal();
|
|
||||||
}
|
|
||||||
|
|
||||||
using ScaleDiagonalReturnType =
|
|
||||||
DiagonalWrapper<const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar, DiagonalVectorType, product)>;
|
|
||||||
|
|
||||||
/** \returns the product of a scalar and the diagonal matrix \a other */
|
|
||||||
EIGEN_DEVICE_FUNC friend inline const ScaleDiagonalReturnType operator*(const Scalar& scalar,
|
|
||||||
const DiagonalBase& other) {
|
|
||||||
return (scalar * other.diagonal()).asDiagonal();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename OtherDerived>
|
|
||||||
using DiagonalSumReturnType = DiagonalWrapper<const EIGEN_CWISE_BINARY_RETURN_TYPE(
|
|
||||||
DiagonalVectorType, typename OtherDerived::DiagonalVectorType, sum)>;
|
|
||||||
|
|
||||||
/** \returns the sum of \c *this and the diagonal matrix \a other */
|
|
||||||
template <typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC inline const DiagonalSumReturnType<OtherDerived> operator+(
|
|
||||||
const DiagonalBase<OtherDerived>& other) const {
|
|
||||||
return (diagonal() + other.diagonal()).asDiagonal();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename OtherDerived>
|
|
||||||
using DiagonalDifferenceReturnType = DiagonalWrapper<const EIGEN_CWISE_BINARY_RETURN_TYPE(
|
|
||||||
DiagonalVectorType, typename OtherDerived::DiagonalVectorType, difference)>;
|
|
||||||
|
|
||||||
/** \returns the difference of \c *this and the diagonal matrix \a other */
|
|
||||||
template <typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC inline const DiagonalDifferenceReturnType<OtherDerived> operator-(
|
|
||||||
const DiagonalBase<OtherDerived>& other) const {
|
|
||||||
return (diagonal() - other.diagonal()).asDiagonal();
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
template<typename DenseDerived>
|
||||||
|
void DiagonalBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const
|
||||||
|
{
|
||||||
|
other.setZero();
|
||||||
|
other.diagonal() = diagonal();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/** \class DiagonalMatrix
|
/** \class DiagonalMatrix
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
*
|
*
|
||||||
* \brief Represents a diagonal matrix with its storage
|
* \brief Represents a diagonal matrix with its storage
|
||||||
*
|
*
|
||||||
* \tparam Scalar_ the type of coefficients
|
* \param _Scalar the type of coefficients
|
||||||
* \tparam SizeAtCompileTime the dimension of the matrix, or Dynamic
|
* \param SizeAtCompileTime the dimension of the matrix, or Dynamic
|
||||||
* \tparam MaxSizeAtCompileTime the dimension of the matrix, or Dynamic. This parameter is optional and defaults
|
* \param MaxSizeAtCompileTime the dimension of the matrix, or Dynamic. This parameter is optional and defaults
|
||||||
* to SizeAtCompileTime. Most of the time, you do not need to specify it.
|
* to SizeAtCompileTime. Most of the time, you do not need to specify it.
|
||||||
*
|
*
|
||||||
* \sa class DiagonalBase, class DiagonalWrapper
|
* \sa class DiagonalWrapper
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
template <typename Scalar_, int SizeAtCompileTime, int MaxSizeAtCompileTime>
|
template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime>
|
||||||
struct traits<DiagonalMatrix<Scalar_, SizeAtCompileTime, MaxSizeAtCompileTime>>
|
struct traits<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> >
|
||||||
: traits<Matrix<Scalar_, SizeAtCompileTime, SizeAtCompileTime, 0, MaxSizeAtCompileTime, MaxSizeAtCompileTime>> {
|
: traits<Matrix<_Scalar,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> >
|
||||||
typedef Matrix<Scalar_, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> DiagonalVectorType;
|
{
|
||||||
typedef DiagonalShape StorageKind;
|
typedef Matrix<_Scalar,SizeAtCompileTime,1,0,MaxSizeAtCompileTime,1> DiagonalVectorType;
|
||||||
enum { Flags = LvalueBit | NoPreferredStorageOrderBit | NestByRefBit };
|
typedef Dense StorageKind;
|
||||||
|
typedef DenseIndex Index;
|
||||||
|
enum {
|
||||||
|
Flags = LvalueBit
|
||||||
};
|
};
|
||||||
} // namespace internal
|
};
|
||||||
template <typename Scalar_, int SizeAtCompileTime, int MaxSizeAtCompileTime>
|
}
|
||||||
class DiagonalMatrix : public DiagonalBase<DiagonalMatrix<Scalar_, SizeAtCompileTime, MaxSizeAtCompileTime>> {
|
template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime>
|
||||||
|
class DiagonalMatrix
|
||||||
|
: public DiagonalBase<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> >
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
typedef typename internal::traits<DiagonalMatrix>::DiagonalVectorType DiagonalVectorType;
|
typedef typename internal::traits<DiagonalMatrix>::DiagonalVectorType DiagonalVectorType;
|
||||||
typedef const DiagonalMatrix& Nested;
|
typedef const DiagonalMatrix& Nested;
|
||||||
typedef Scalar_ Scalar;
|
typedef _Scalar Scalar;
|
||||||
typedef typename internal::traits<DiagonalMatrix>::StorageKind StorageKind;
|
typedef typename internal::traits<DiagonalMatrix>::StorageKind StorageKind;
|
||||||
typedef typename internal::traits<DiagonalMatrix>::StorageIndex StorageIndex;
|
typedef typename internal::traits<DiagonalMatrix>::Index Index;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
DiagonalVectorType m_diagonal;
|
DiagonalVectorType m_diagonal;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** const version of diagonal(). */
|
/** const version of diagonal(). */
|
||||||
EIGEN_DEVICE_FUNC constexpr inline const DiagonalVectorType& diagonal() const { return m_diagonal; }
|
inline const DiagonalVectorType& diagonal() const { return m_diagonal; }
|
||||||
/** \returns a reference to the stored vector of diagonal coefficients. */
|
/** \returns a reference to the stored vector of diagonal coefficients. */
|
||||||
EIGEN_DEVICE_FUNC constexpr inline DiagonalVectorType& diagonal() { return m_diagonal; }
|
inline DiagonalVectorType& diagonal() { return m_diagonal; }
|
||||||
|
|
||||||
/** Default constructor without initialization */
|
/** Default constructor without initialization */
|
||||||
EIGEN_DEVICE_FUNC constexpr inline DiagonalMatrix() {}
|
inline DiagonalMatrix() {}
|
||||||
|
|
||||||
/** Constructs a diagonal matrix with given dimension */
|
/** Constructs a diagonal matrix with given dimension */
|
||||||
EIGEN_DEVICE_FUNC constexpr explicit inline DiagonalMatrix(Index dim) : m_diagonal(dim) {}
|
inline DiagonalMatrix(Index dim) : m_diagonal(dim) {}
|
||||||
|
|
||||||
/** 2D constructor. */
|
/** 2D constructor. */
|
||||||
EIGEN_DEVICE_FUNC constexpr inline DiagonalMatrix(const Scalar& x, const Scalar& y) : m_diagonal(x, y) {}
|
inline DiagonalMatrix(const Scalar& x, const Scalar& y) : m_diagonal(x,y) {}
|
||||||
|
|
||||||
/** 3D constructor. */
|
/** 3D constructor. */
|
||||||
EIGEN_DEVICE_FUNC constexpr inline DiagonalMatrix(const Scalar& x, const Scalar& y, const Scalar& z)
|
inline DiagonalMatrix(const Scalar& x, const Scalar& y, const Scalar& z) : m_diagonal(x,y,z) {}
|
||||||
: m_diagonal(x, y, z) {}
|
|
||||||
|
|
||||||
/** \brief Construct a diagonal matrix with fixed size from an arbitrary number of 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 constexpr 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) {}
|
|
||||||
|
|
||||||
/** \brief Constructs a DiagonalMatrix from an r-value diagonal vector type */
|
|
||||||
EIGEN_DEVICE_FUNC constexpr explicit inline DiagonalMatrix(DiagonalVectorType&& diag) : m_diagonal(std::move(diag)) {}
|
|
||||||
|
|
||||||
/** Copy constructor. */
|
/** Copy constructor. */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC constexpr inline DiagonalMatrix(const DiagonalBase<OtherDerived>& other)
|
inline DiagonalMatrix(const DiagonalBase<OtherDerived>& other) : m_diagonal(other.diagonal()) {}
|
||||||
: m_diagonal(other.diagonal()) {}
|
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
/** copy constructor. prevent a default copy constructor from hiding the other templated constructor */
|
/** copy constructor. prevent a default copy constructor from hiding the other templated constructor */
|
||||||
@@ -236,12 +174,13 @@ class DiagonalMatrix : public DiagonalBase<DiagonalMatrix<Scalar_, SizeAtCompile
|
|||||||
|
|
||||||
/** generic constructor from expression of the diagonal coefficients */
|
/** generic constructor from expression of the diagonal coefficients */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC constexpr explicit inline DiagonalMatrix(const MatrixBase<OtherDerived>& other)
|
explicit inline DiagonalMatrix(const MatrixBase<OtherDerived>& other) : m_diagonal(other)
|
||||||
: m_diagonal(other) {}
|
{}
|
||||||
|
|
||||||
/** Copy operator. */
|
/** Copy operator. */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC DiagonalMatrix& operator=(const DiagonalBase<OtherDerived>& other) {
|
DiagonalMatrix& operator=(const DiagonalBase<OtherDerived>& other)
|
||||||
|
{
|
||||||
m_diagonal = other.diagonal();
|
m_diagonal = other.diagonal();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -250,41 +189,23 @@ class DiagonalMatrix : public DiagonalBase<DiagonalMatrix<Scalar_, SizeAtCompile
|
|||||||
/** This is a special case of the templated operator=. Its purpose is to
|
/** This is a special case of the templated operator=. Its purpose is to
|
||||||
* prevent a default operator= from hiding the templated operator=.
|
* prevent a default operator= from hiding the templated operator=.
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC DiagonalMatrix& operator=(const DiagonalMatrix& other) {
|
DiagonalMatrix& operator=(const DiagonalMatrix& other)
|
||||||
|
{
|
||||||
m_diagonal = other.diagonal();
|
m_diagonal = other.diagonal();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef DiagonalWrapper<const CwiseNullaryOp<internal::scalar_constant_op<Scalar>, DiagonalVectorType>>
|
|
||||||
InitializeReturnType;
|
|
||||||
|
|
||||||
typedef DiagonalWrapper<const CwiseNullaryOp<internal::scalar_zero_op<Scalar>, DiagonalVectorType>>
|
|
||||||
ZeroInitializeReturnType;
|
|
||||||
|
|
||||||
/** Initializes a diagonal matrix of size SizeAtCompileTime with coefficients set to zero */
|
|
||||||
EIGEN_DEVICE_FUNC static const ZeroInitializeReturnType Zero() { return DiagonalVectorType::Zero().asDiagonal(); }
|
|
||||||
/** Initializes a diagonal matrix of size dim with coefficients set to zero */
|
|
||||||
EIGEN_DEVICE_FUNC static const ZeroInitializeReturnType Zero(Index size) {
|
|
||||||
return DiagonalVectorType::Zero(size).asDiagonal();
|
|
||||||
}
|
|
||||||
/** Initializes a identity matrix of size SizeAtCompileTime */
|
|
||||||
EIGEN_DEVICE_FUNC static const InitializeReturnType Identity() { return DiagonalVectorType::Ones().asDiagonal(); }
|
|
||||||
/** Initializes a identity matrix of size dim */
|
|
||||||
EIGEN_DEVICE_FUNC static const InitializeReturnType Identity(Index size) {
|
|
||||||
return DiagonalVectorType::Ones(size).asDiagonal();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Resizes to given size. */
|
/** Resizes to given size. */
|
||||||
EIGEN_DEVICE_FUNC inline void resize(Index size) { m_diagonal.resize(size); }
|
inline void resize(Index size) { m_diagonal.resize(size); }
|
||||||
/** Sets all coefficients to zero. */
|
/** Sets all coefficients to zero. */
|
||||||
EIGEN_DEVICE_FUNC inline void setZero() { m_diagonal.setZero(); }
|
inline void setZero() { m_diagonal.setZero(); }
|
||||||
/** Resizes and sets all coefficients to zero. */
|
/** Resizes and sets all coefficients to zero. */
|
||||||
EIGEN_DEVICE_FUNC inline void setZero(Index size) { m_diagonal.setZero(size); }
|
inline void setZero(Index size) { m_diagonal.setZero(size); }
|
||||||
/** Sets this matrix to be the identity matrix of the current size. */
|
/** Sets this matrix to be the identity matrix of the current size. */
|
||||||
EIGEN_DEVICE_FUNC inline void setIdentity() { m_diagonal.setOnes(); }
|
inline void setIdentity() { m_diagonal.setOnes(); }
|
||||||
/** Sets this matrix to be the identity matrix of the given size. */
|
/** Sets this matrix to be the identity matrix of the given size. */
|
||||||
EIGEN_DEVICE_FUNC inline void setIdentity(Index size) { m_diagonal.setOnes(size); }
|
inline void setIdentity(Index size) { m_diagonal.setOnes(size); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \class DiagonalWrapper
|
/** \class DiagonalWrapper
|
||||||
@@ -292,7 +213,7 @@ class DiagonalMatrix : public DiagonalBase<DiagonalMatrix<Scalar_, SizeAtCompile
|
|||||||
*
|
*
|
||||||
* \brief Expression of a diagonal matrix
|
* \brief Expression of a diagonal matrix
|
||||||
*
|
*
|
||||||
* \tparam DiagonalVectorType_ the type of the vector of diagonal coefficients
|
* \param _DiagonalVectorType the type of the vector of diagonal coefficients
|
||||||
*
|
*
|
||||||
* This class is an expression of a diagonal matrix, but not storing its own vector of diagonal coefficients,
|
* This class is an expression of a diagonal matrix, but not storing its own vector of diagonal coefficients,
|
||||||
* instead wrapping an existing vector expression. It is the return type of MatrixBase::asDiagonal()
|
* instead wrapping an existing vector expression. It is the return type of MatrixBase::asDiagonal()
|
||||||
@@ -302,40 +223,41 @@ class DiagonalMatrix : public DiagonalBase<DiagonalMatrix<Scalar_, SizeAtCompile
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
template <typename DiagonalVectorType_>
|
template<typename _DiagonalVectorType>
|
||||||
struct traits<DiagonalWrapper<DiagonalVectorType_>> {
|
struct traits<DiagonalWrapper<_DiagonalVectorType> >
|
||||||
typedef DiagonalVectorType_ DiagonalVectorType;
|
{
|
||||||
|
typedef _DiagonalVectorType DiagonalVectorType;
|
||||||
typedef typename DiagonalVectorType::Scalar Scalar;
|
typedef typename DiagonalVectorType::Scalar Scalar;
|
||||||
typedef typename DiagonalVectorType::StorageIndex StorageIndex;
|
typedef typename DiagonalVectorType::Index Index;
|
||||||
typedef DiagonalShape StorageKind;
|
typedef typename DiagonalVectorType::StorageKind StorageKind;
|
||||||
typedef typename traits<DiagonalVectorType>::XprKind XprKind;
|
|
||||||
enum {
|
enum {
|
||||||
RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
|
RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
|
||||||
ColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
|
ColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
|
||||||
MaxRowsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
|
MaxRowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
|
||||||
MaxColsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
|
MaxColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
|
||||||
Flags = (traits<DiagonalVectorType>::Flags & LvalueBit) | NoPreferredStorageOrderBit
|
Flags = traits<DiagonalVectorType>::Flags & LvalueBit
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} // namespace internal
|
}
|
||||||
|
|
||||||
template <typename DiagonalVectorType_>
|
template<typename _DiagonalVectorType>
|
||||||
class DiagonalWrapper : public DiagonalBase<DiagonalWrapper<DiagonalVectorType_>>, internal::no_assignment_operator {
|
class DiagonalWrapper
|
||||||
|
: public DiagonalBase<DiagonalWrapper<_DiagonalVectorType> >, internal::no_assignment_operator
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
typedef DiagonalVectorType_ DiagonalVectorType;
|
typedef _DiagonalVectorType DiagonalVectorType;
|
||||||
typedef DiagonalWrapper Nested;
|
typedef DiagonalWrapper Nested;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Constructor from expression of diagonal coefficients to wrap. */
|
/** Constructor from expression of diagonal coefficients to wrap. */
|
||||||
EIGEN_DEVICE_FUNC constexpr explicit inline DiagonalWrapper(DiagonalVectorType& a_diagonal)
|
inline DiagonalWrapper(const DiagonalVectorType& diagonal) : m_diagonal(diagonal) {}
|
||||||
: m_diagonal(a_diagonal) {}
|
|
||||||
|
|
||||||
/** \returns a const reference to the wrapped expression of diagonal coefficients. */
|
/** \returns a const reference to the wrapped expression of diagonal coefficients. */
|
||||||
EIGEN_DEVICE_FUNC constexpr const DiagonalVectorType& diagonal() const { return m_diagonal; }
|
const DiagonalVectorType& diagonal() const { return m_diagonal; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typename DiagonalVectorType::Nested m_diagonal;
|
const typename DiagonalVectorType::Nested m_diagonal;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \returns a pseudo-expression of a diagonal matrix with *this as vector of diagonal coefficients
|
/** \returns a pseudo-expression of a diagonal matrix with *this as vector of diagonal coefficients
|
||||||
@@ -348,8 +270,10 @@ class DiagonalWrapper : public DiagonalBase<DiagonalWrapper<DiagonalVectorType_>
|
|||||||
* \sa class DiagonalWrapper, class DiagonalMatrix, diagonal(), isDiagonal()
|
* \sa class DiagonalWrapper, class DiagonalMatrix, diagonal(), isDiagonal()
|
||||||
**/
|
**/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC constexpr const DiagonalWrapper<const Derived> MatrixBase<Derived>::asDiagonal() const {
|
inline const DiagonalWrapper<const Derived>
|
||||||
return DiagonalWrapper<const Derived>(derived());
|
MatrixBase<Derived>::asDiagonal() const
|
||||||
|
{
|
||||||
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns true if *this is approximately equal to a diagonal matrix,
|
/** \returns true if *this is approximately equal to a diagonal matrix,
|
||||||
@@ -361,113 +285,22 @@ EIGEN_DEVICE_FUNC constexpr const DiagonalWrapper<const Derived> MatrixBase<Deri
|
|||||||
* \sa asDiagonal()
|
* \sa asDiagonal()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
bool MatrixBase<Derived>::isDiagonal(const RealScalar& prec) const {
|
bool MatrixBase<Derived>::isDiagonal(RealScalar prec) const
|
||||||
|
{
|
||||||
if(cols() != rows()) return false;
|
if(cols() != rows()) return false;
|
||||||
RealScalar maxAbsOnDiagonal = static_cast<RealScalar>(-1);
|
RealScalar maxAbsOnDiagonal = static_cast<RealScalar>(-1);
|
||||||
for (Index j = 0; j < cols(); ++j) {
|
for(Index j = 0; j < cols(); ++j)
|
||||||
RealScalar absOnDiagonal = numext::abs(coeff(j, j));
|
{
|
||||||
|
RealScalar absOnDiagonal = internal::abs(coeff(j,j));
|
||||||
if(absOnDiagonal > maxAbsOnDiagonal) maxAbsOnDiagonal = absOnDiagonal;
|
if(absOnDiagonal > maxAbsOnDiagonal) maxAbsOnDiagonal = absOnDiagonal;
|
||||||
}
|
}
|
||||||
for(Index j = 0; j < cols(); ++j)
|
for(Index j = 0; j < cols(); ++j)
|
||||||
for (Index i = 0; i < j; ++i) {
|
for(Index i = 0; i < j; ++i)
|
||||||
|
{
|
||||||
if(!internal::isMuchSmallerThan(coeff(i, j), maxAbsOnDiagonal, prec)) return false;
|
if(!internal::isMuchSmallerThan(coeff(i, j), maxAbsOnDiagonal, prec)) return false;
|
||||||
if(!internal::isMuchSmallerThan(coeff(j, i), maxAbsOnDiagonal, prec)) return false;
|
if(!internal::isMuchSmallerThan(coeff(j, i), maxAbsOnDiagonal, prec)) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns DiagonalWrapper.
|
|
||||||
*
|
|
||||||
* Example: \include MatrixBase_diagonalView.cpp
|
|
||||||
* Output: \verbinclude MatrixBase_diagonalView.out
|
|
||||||
*
|
|
||||||
* \sa diagonalView()
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** This is the non-const version of diagonalView() with DiagIndex_ . */
|
|
||||||
template <typename Derived>
|
|
||||||
template <int DiagIndex_>
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DiagonalWrapper<Diagonal<Derived, DiagIndex_>> MatrixBase<Derived>::diagonalView() {
|
|
||||||
typedef Diagonal<Derived, DiagIndex_> DiagType;
|
|
||||||
typedef DiagonalWrapper<DiagType> ReturnType;
|
|
||||||
DiagType diag(this->derived());
|
|
||||||
return ReturnType(diag);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** This is the const version of diagonalView() with DiagIndex_ . */
|
|
||||||
template <typename Derived>
|
|
||||||
template <int DiagIndex_>
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DiagonalWrapper<Diagonal<const Derived, DiagIndex_>> MatrixBase<Derived>::diagonalView()
|
|
||||||
const {
|
|
||||||
typedef Diagonal<const Derived, DiagIndex_> DiagType;
|
|
||||||
typedef DiagonalWrapper<DiagType> ReturnType;
|
|
||||||
DiagType diag(this->derived());
|
|
||||||
return ReturnType(diag);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** This is the non-const version of diagonalView() with dynamic index. */
|
|
||||||
template <typename Derived>
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DiagonalWrapper<Diagonal<Derived, DynamicIndex>> MatrixBase<Derived>::diagonalView(
|
|
||||||
Index index) {
|
|
||||||
typedef Diagonal<Derived, DynamicIndex> DiagType;
|
|
||||||
typedef DiagonalWrapper<DiagType> ReturnType;
|
|
||||||
DiagType diag(this->derived(), index);
|
|
||||||
return ReturnType(diag);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** This is the const version of diagonalView() with dynamic index. */
|
|
||||||
template <typename Derived>
|
|
||||||
EIGEN_DEVICE_FUNC constexpr DiagonalWrapper<Diagonal<const Derived, DynamicIndex>> MatrixBase<Derived>::diagonalView(
|
|
||||||
Index index) const {
|
|
||||||
typedef Diagonal<const Derived, DynamicIndex> DiagType;
|
|
||||||
typedef DiagonalWrapper<DiagType> ReturnType;
|
|
||||||
DiagType diag(this->derived(), index);
|
|
||||||
return ReturnType(diag);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct storage_kind_to_shape<DiagonalShape> {
|
|
||||||
typedef DiagonalShape Shape;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Diagonal2Dense {};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct AssignmentKind<DenseShape, DiagonalShape> {
|
|
||||||
typedef Diagonal2Dense Kind;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Diagonal matrix to Dense assignment
|
|
||||||
template <typename DstXprType, typename SrcXprType, typename Functor>
|
|
||||||
struct Assignment<DstXprType, SrcXprType, Functor, Diagonal2Dense> {
|
|
||||||
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 dstCols = src.cols();
|
|
||||||
if ((dst.rows() != dstRows) || (dst.cols() != dstCols)) dst.resize(dstRows, dstCols);
|
|
||||||
|
|
||||||
dst.setZero();
|
|
||||||
dst.diagonal() = src.diagonal();
|
|
||||||
}
|
|
||||||
|
|
||||||
static EIGEN_DEVICE_FUNC void run(
|
|
||||||
DstXprType& dst, const SrcXprType& src,
|
|
||||||
const internal::add_assign_op<typename DstXprType::Scalar, typename SrcXprType::Scalar>& /*func*/) {
|
|
||||||
dst.diagonal() += src.diagonal();
|
|
||||||
}
|
|
||||||
|
|
||||||
static EIGEN_DEVICE_FUNC void run(
|
|
||||||
DstXprType& dst, const SrcXprType& src,
|
|
||||||
const internal::sub_assign_op<typename DstXprType::Scalar, typename SrcXprType::Scalar>& /*func*/) {
|
|
||||||
dst.diagonal() -= src.diagonal();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_DIAGONALMATRIX_H
|
#endif // EIGEN_DIAGONALMATRIX_H
|
||||||
|
|||||||
@@ -4,27 +4,132 @@
|
|||||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
// Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
|
// Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_DIAGONALPRODUCT_H
|
#ifndef EIGEN_DIAGONALPRODUCT_H
|
||||||
#define EIGEN_DIAGONALPRODUCT_H
|
#define EIGEN_DIAGONALPRODUCT_H
|
||||||
|
|
||||||
// IWYU pragma: private
|
namespace internal {
|
||||||
#include "./InternalHeaderCheck.h"
|
template<typename MatrixType, typename DiagonalType, int ProductOrder>
|
||||||
|
struct traits<DiagonalProduct<MatrixType, DiagonalType, ProductOrder> >
|
||||||
|
: traits<MatrixType>
|
||||||
|
{
|
||||||
|
typedef typename scalar_product_traits<typename MatrixType::Scalar, typename DiagonalType::Scalar>::ReturnType Scalar;
|
||||||
|
enum {
|
||||||
|
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
|
||||||
|
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
|
||||||
|
MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
|
||||||
|
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
|
||||||
|
|
||||||
namespace Eigen {
|
_StorageOrder = MatrixType::Flags & RowMajorBit ? RowMajor : ColMajor,
|
||||||
|
_PacketOnDiag = !((int(_StorageOrder) == RowMajor && int(ProductOrder) == OnTheLeft)
|
||||||
|
||(int(_StorageOrder) == ColMajor && int(ProductOrder) == OnTheRight)),
|
||||||
|
_SameTypes = is_same<typename MatrixType::Scalar, typename DiagonalType::Scalar>::value,
|
||||||
|
// FIXME currently we need same types, but in the future the next rule should be the one
|
||||||
|
//_Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && ((!_PacketOnDiag) || (_SameTypes && bool(int(DiagonalType::Flags)&PacketAccessBit))),
|
||||||
|
_Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && _SameTypes && ((!_PacketOnDiag) || (bool(int(DiagonalType::Flags)&PacketAccessBit))),
|
||||||
|
|
||||||
|
Flags = (HereditaryBits & (unsigned int)(MatrixType::Flags)) | (_Vectorizable ? PacketAccessBit : 0),
|
||||||
|
CoeffReadCost = NumTraits<Scalar>::MulCost + MatrixType::CoeffReadCost + DiagonalType::DiagonalVectorType::CoeffReadCost
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename MatrixType, typename DiagonalType, int ProductOrder>
|
||||||
|
class DiagonalProduct : internal::no_assignment_operator,
|
||||||
|
public MatrixBase<DiagonalProduct<MatrixType, DiagonalType, ProductOrder> >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef MatrixBase<DiagonalProduct> Base;
|
||||||
|
EIGEN_DENSE_PUBLIC_INTERFACE(DiagonalProduct)
|
||||||
|
|
||||||
|
inline DiagonalProduct(const MatrixType& matrix, const DiagonalType& diagonal)
|
||||||
|
: m_matrix(matrix), m_diagonal(diagonal)
|
||||||
|
{
|
||||||
|
eigen_assert(diagonal.diagonal().size() == (ProductOrder == OnTheLeft ? matrix.rows() : matrix.cols()));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Index rows() const { return m_matrix.rows(); }
|
||||||
|
inline Index cols() const { return m_matrix.cols(); }
|
||||||
|
|
||||||
|
const Scalar coeff(Index row, Index col) const
|
||||||
|
{
|
||||||
|
return m_diagonal.diagonal().coeff(ProductOrder == OnTheLeft ? row : col) * m_matrix.coeff(row, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
StorageOrder = Flags & RowMajorBit ? RowMajor : ColMajor
|
||||||
|
};
|
||||||
|
const Index indexInDiagonalVector = ProductOrder == OnTheLeft ? row : col;
|
||||||
|
|
||||||
|
return packet_impl<LoadMode>(row,col,indexInDiagonalVector,typename internal::conditional<
|
||||||
|
((int(StorageOrder) == RowMajor && int(ProductOrder) == OnTheLeft)
|
||||||
|
||(int(StorageOrder) == ColMajor && int(ProductOrder) == OnTheRight)), internal::true_type, internal::false_type>::type());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
template<int LoadMode>
|
||||||
|
EIGEN_STRONG_INLINE PacketScalar packet_impl(Index row, Index col, Index id, internal::true_type) const
|
||||||
|
{
|
||||||
|
return internal::pmul(m_matrix.template packet<LoadMode>(row, col),
|
||||||
|
internal::pset1<PacketScalar>(m_diagonal.diagonal().coeff(id)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
EIGEN_STRONG_INLINE PacketScalar packet_impl(Index row, Index col, Index id, internal::false_type) const
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
InnerSize = (MatrixType::Flags & RowMajorBit) ? MatrixType::ColsAtCompileTime : MatrixType::RowsAtCompileTime,
|
||||||
|
DiagonalVectorPacketLoadMode = (LoadMode == Aligned && ((InnerSize%16) == 0)) ? Aligned : Unaligned
|
||||||
|
};
|
||||||
|
return internal::pmul(m_matrix.template packet<LoadMode>(row, col),
|
||||||
|
m_diagonal.diagonal().template packet<DiagonalVectorPacketLoadMode>(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
const typename MatrixType::Nested m_matrix;
|
||||||
|
const typename DiagonalType::Nested m_diagonal;
|
||||||
|
};
|
||||||
|
|
||||||
/** \returns the diagonal matrix product of \c *this by the diagonal matrix \a diagonal.
|
/** \returns the diagonal matrix product of \c *this by the diagonal matrix \a diagonal.
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename DiagonalDerived>
|
template<typename DiagonalDerived>
|
||||||
EIGEN_DEVICE_FUNC inline const Product<Derived, DiagonalDerived, LazyProduct> MatrixBase<Derived>::operator*(
|
inline const DiagonalProduct<Derived, DiagonalDerived, OnTheRight>
|
||||||
const DiagonalBase<DiagonalDerived> &a_diagonal) const {
|
MatrixBase<Derived>::operator*(const DiagonalBase<DiagonalDerived> &diagonal) const
|
||||||
return Product<Derived, DiagonalDerived, LazyProduct>(derived(), a_diagonal.derived());
|
{
|
||||||
|
return DiagonalProduct<Derived, DiagonalDerived, OnTheRight>(derived(), diagonal.derived());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \returns the diagonal matrix product of \c *this by the matrix \a matrix.
|
||||||
|
*/
|
||||||
|
template<typename DiagonalDerived>
|
||||||
|
template<typename MatrixDerived>
|
||||||
|
inline const DiagonalProduct<MatrixDerived, DiagonalDerived, OnTheLeft>
|
||||||
|
DiagonalBase<DiagonalDerived>::operator*(const MatrixBase<MatrixDerived> &matrix) const
|
||||||
|
{
|
||||||
|
return DiagonalProduct<MatrixDerived, DiagonalDerived, OnTheLeft>(matrix.derived(), derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_DIAGONALPRODUCT_H
|
#endif // EIGEN_DIAGONALPRODUCT_H
|
||||||
|
|||||||
@@ -3,37 +3,64 @@
|
|||||||
//
|
//
|
||||||
// Copyright (C) 2006-2008, 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
|
// Copyright (C) 2006-2008, 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_DOT_H
|
#ifndef EIGEN_DOT_H
|
||||||
#define EIGEN_DOT_H
|
#define EIGEN_DOT_H
|
||||||
|
|
||||||
// IWYU pragma: private
|
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template <typename Derived, typename Scalar = typename traits<Derived>::Scalar>
|
// helper function for dot(). The problem is that if we put that in the body of dot(), then upon calling dot
|
||||||
struct squared_norm_impl {
|
// with mismatched types, the compiler emits errors about failing to instantiate cwiseProduct BEFORE
|
||||||
using Real = typename NumTraits<Scalar>::Real;
|
// looking at the static assertions. Thus this is a trick to get better compile errors.
|
||||||
static EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Real run(const Derived& a) {
|
template<typename T, typename U,
|
||||||
return a.realView().cwiseAbs2().sum();
|
// the NeedToTranspose condition here is taken straight from Assign.h
|
||||||
|
bool NeedToTranspose = T::IsVectorAtCompileTime
|
||||||
|
&& U::IsVectorAtCompileTime
|
||||||
|
&& ((int(T::RowsAtCompileTime) == 1 && int(U::ColsAtCompileTime) == 1)
|
||||||
|
| // FIXME | instead of || to please GCC 4.4.0 stupid warning "suggest parentheses around &&".
|
||||||
|
// revert to || as soon as not needed anymore.
|
||||||
|
(int(T::ColsAtCompileTime) == 1 && int(U::RowsAtCompileTime) == 1))
|
||||||
|
>
|
||||||
|
struct dot_nocheck
|
||||||
|
{
|
||||||
|
typedef typename scalar_product_traits<typename traits<T>::Scalar,typename traits<U>::Scalar>::ReturnType ResScalar;
|
||||||
|
static inline ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b)
|
||||||
|
{
|
||||||
|
return a.template binaryExpr<scalar_conj_product_op<typename traits<T>::Scalar,typename traits<U>::Scalar> >(b).sum();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Derived>
|
template<typename T, typename U>
|
||||||
struct squared_norm_impl<Derived, bool> {
|
struct dot_nocheck<T, U, true>
|
||||||
static EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE bool run(const Derived& a) { return a.any(); }
|
{
|
||||||
|
typedef typename scalar_product_traits<typename traits<T>::Scalar,typename traits<U>::Scalar>::ReturnType ResScalar;
|
||||||
|
static inline ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b)
|
||||||
|
{
|
||||||
|
return a.transpose().template binaryExpr<scalar_conj_product_op<typename traits<T>::Scalar,typename traits<U>::Scalar> >(b).sum();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
/** \fn MatrixBase::dot
|
/** \returns the dot product of *this with other.
|
||||||
* \returns the dot product of *this with other.
|
|
||||||
*
|
*
|
||||||
* \only_for_vectors
|
* \only_for_vectors
|
||||||
*
|
*
|
||||||
@@ -45,117 +72,100 @@ struct squared_norm_impl<Derived, bool> {
|
|||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE
|
typename internal::scalar_product_traits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType
|
||||||
typename ScalarBinaryOpTraits<typename internal::traits<Derived>::Scalar,
|
MatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const
|
||||||
typename internal::traits<OtherDerived>::Scalar>::ReturnType
|
{
|
||||||
MatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const {
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
return internal::dot_impl<Derived, OtherDerived>::run(derived(), other.derived());
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
|
||||||
|
EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived)
|
||||||
|
typedef internal::scalar_conj_product_op<Scalar,typename OtherDerived::Scalar> func;
|
||||||
|
EIGEN_CHECK_BINARY_COMPATIBILIY(func,Scalar,typename OtherDerived::Scalar);
|
||||||
|
|
||||||
|
eigen_assert(size() == other.size());
|
||||||
|
|
||||||
|
return internal::dot_nocheck<Derived,OtherDerived>::run(*this, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef EIGEN2_SUPPORT
|
||||||
|
/** \returns the dot product of *this with other, with the Eigen2 convention that the dot product is linear in the first variable
|
||||||
|
* (conjugating the second variable). Of course this only makes a difference in the complex case.
|
||||||
|
*
|
||||||
|
* This method is only available in EIGEN2_SUPPORT mode.
|
||||||
|
*
|
||||||
|
* \only_for_vectors
|
||||||
|
*
|
||||||
|
* \sa dot()
|
||||||
|
*/
|
||||||
|
template<typename Derived>
|
||||||
|
template<typename OtherDerived>
|
||||||
|
typename internal::traits<Derived>::Scalar
|
||||||
|
MatrixBase<Derived>::eigen2_dot(const MatrixBase<OtherDerived>& other) const
|
||||||
|
{
|
||||||
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
|
||||||
|
EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived)
|
||||||
|
EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value),
|
||||||
|
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||||
|
|
||||||
|
eigen_assert(size() == other.size());
|
||||||
|
|
||||||
|
return internal::dot_nocheck<OtherDerived,Derived>::run(other,*this);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//---------- implementation of L2 norm and related functions ----------
|
//---------- implementation of L2 norm and related functions ----------
|
||||||
|
|
||||||
/** \returns, for vectors, the squared \em l2 norm of \c *this, and for matrices the squared Frobenius norm.
|
/** \returns, for vectors, the squared \em l2 norm of \c *this, and for matrices the Frobenius norm.
|
||||||
* In both cases, it consists in the sum of the square of all the matrix entries.
|
* In both cases, it consists in the sum of the square of all the matrix entries.
|
||||||
* For vectors, this is also equal to the dot product of \c *this with itself.
|
* For vectors, this is also equals to the dot product of \c *this with itself.
|
||||||
*
|
*
|
||||||
* \sa dot(), norm(), lpNorm()
|
* \sa dot(), norm()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
|
EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::squaredNorm() const
|
||||||
MatrixBase<Derived>::squaredNorm() const {
|
{
|
||||||
return internal::squared_norm_impl<Derived>::run(derived());
|
return internal::real((*this).cwiseAbs2().sum());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns, for vectors, the \em l2 norm of \c *this, and for matrices the Frobenius norm.
|
/** \returns, for vectors, the \em l2 norm of \c *this, and for matrices the Frobenius norm.
|
||||||
* In both cases, it consists in the square root of the sum of the square of all the matrix entries.
|
* In both cases, it consists in the square root of the sum of the square of all the matrix entries.
|
||||||
* For vectors, this is also equal to the square root of the dot product of \c *this with itself.
|
* For vectors, this is also equals to the square root of the dot product of \c *this with itself.
|
||||||
*
|
*
|
||||||
* \sa lpNorm(), dot(), squaredNorm()
|
* \sa dot(), squaredNorm()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
|
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::norm() const
|
||||||
MatrixBase<Derived>::norm() const {
|
{
|
||||||
return numext::sqrt(squaredNorm());
|
return internal::sqrt(squaredNorm());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns an expression of the quotient of \c *this by its own norm.
|
/** \returns an expression of the quotient of *this by its own norm.
|
||||||
*
|
|
||||||
* \warning If the input vector is too small (i.e., this->norm()==0),
|
|
||||||
* then this function returns a copy of the input.
|
|
||||||
*
|
*
|
||||||
* \only_for_vectors
|
* \only_for_vectors
|
||||||
*
|
*
|
||||||
* \sa norm(), normalize()
|
* \sa norm(), normalize()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::PlainObject MatrixBase<Derived>::normalized()
|
inline const typename MatrixBase<Derived>::PlainObject
|
||||||
const {
|
MatrixBase<Derived>::normalized() const
|
||||||
typedef typename internal::nested_eval<Derived, 2>::type Nested_;
|
{
|
||||||
Nested_ n(derived());
|
typedef typename internal::nested<Derived>::type Nested;
|
||||||
RealScalar z = n.squaredNorm();
|
typedef typename internal::remove_reference<Nested>::type _Nested;
|
||||||
// NOTE: after extensive benchmarking, this conditional does not impact performance, at least on recent x86 CPU
|
_Nested n(derived());
|
||||||
if (z > RealScalar(0))
|
return n / n.norm();
|
||||||
return n / numext::sqrt(z);
|
|
||||||
else
|
|
||||||
return n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Normalizes the vector, i.e. divides it by its own norm.
|
/** Normalizes the vector, i.e. divides it by its own norm.
|
||||||
*
|
*
|
||||||
* \only_for_vectors
|
* \only_for_vectors
|
||||||
*
|
*
|
||||||
* \warning If the input vector is too small (i.e., this->norm()==0), then \c *this is left unchanged.
|
|
||||||
*
|
|
||||||
* \sa norm(), normalized()
|
* \sa norm(), normalized()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void MatrixBase<Derived>::normalize() {
|
inline void MatrixBase<Derived>::normalize()
|
||||||
RealScalar z = squaredNorm();
|
{
|
||||||
// NOTE: after extensive benchmarking, this conditional does not impact performance, at least on recent x86 CPU
|
*this /= norm();
|
||||||
if (z > RealScalar(0)) derived() /= numext::sqrt(z);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \returns an expression of the quotient of \c *this by its own norm while avoiding underflow and overflow.
|
|
||||||
*
|
|
||||||
* \only_for_vectors
|
|
||||||
*
|
|
||||||
* This method is analogue to the normalized() method, but it reduces the risk of
|
|
||||||
* underflow and overflow when computing the norm.
|
|
||||||
*
|
|
||||||
* \warning If the input vector is too small (i.e., this->norm()==0),
|
|
||||||
* then this function returns a copy of the input.
|
|
||||||
*
|
|
||||||
* \sa stableNorm(), stableNormalize(), normalized()
|
|
||||||
*/
|
|
||||||
template <typename Derived>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::PlainObject
|
|
||||||
MatrixBase<Derived>::stableNormalized() const {
|
|
||||||
typedef typename internal::nested_eval<Derived, 3>::type Nested_;
|
|
||||||
Nested_ n(derived());
|
|
||||||
RealScalar w = n.cwiseAbs().maxCoeff();
|
|
||||||
RealScalar z = (n / w).squaredNorm();
|
|
||||||
if (z > RealScalar(0))
|
|
||||||
return n / (numext::sqrt(z) * w);
|
|
||||||
else
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Normalizes the vector while avoid underflow and overflow
|
|
||||||
*
|
|
||||||
* \only_for_vectors
|
|
||||||
*
|
|
||||||
* This method is analogue to the normalize() method, but it reduces the risk of
|
|
||||||
* underflow and overflow when computing the norm.
|
|
||||||
*
|
|
||||||
* \warning If the input vector is too small (i.e., this->norm()==0), then \c *this is left unchanged.
|
|
||||||
*
|
|
||||||
* \sa stableNorm(), stableNormalized(), normalize()
|
|
||||||
*/
|
|
||||||
template <typename Derived>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void MatrixBase<Derived>::stableNormalize() {
|
|
||||||
RealScalar w = cwiseAbs().maxCoeff();
|
|
||||||
RealScalar z = (derived() / w).squaredNorm();
|
|
||||||
if (z > RealScalar(0)) derived() /= numext::sqrt(z) * w;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------- implementation of other norms ----------
|
//---------- implementation of other norms ----------
|
||||||
@@ -163,64 +173,55 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void MatrixBase<Derived>::stableNormalize(
|
|||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template<typename Derived, int p>
|
template<typename Derived, int p>
|
||||||
struct lpNorm_selector {
|
struct lpNorm_selector
|
||||||
|
{
|
||||||
typedef typename NumTraits<typename traits<Derived>::Scalar>::Real RealScalar;
|
typedef typename NumTraits<typename traits<Derived>::Scalar>::Real RealScalar;
|
||||||
EIGEN_DEVICE_FUNC static inline RealScalar run(const MatrixBase<Derived>& m) {
|
inline static RealScalar run(const MatrixBase<Derived>& m)
|
||||||
EIGEN_USING_STD(pow)
|
{
|
||||||
return pow(m.cwiseAbs().array().pow(p).sum(), RealScalar(1)/p);
|
return pow(m.cwiseAbs().array().pow(p).sum(), RealScalar(1)/p);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
struct lpNorm_selector<Derived, 1> {
|
struct lpNorm_selector<Derived, 1>
|
||||||
EIGEN_DEVICE_FUNC static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(
|
{
|
||||||
const MatrixBase<Derived>& m) {
|
inline static typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
|
||||||
|
{
|
||||||
return m.cwiseAbs().sum();
|
return m.cwiseAbs().sum();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
struct lpNorm_selector<Derived, 2> {
|
struct lpNorm_selector<Derived, 2>
|
||||||
EIGEN_DEVICE_FUNC static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(
|
{
|
||||||
const MatrixBase<Derived>& m) {
|
inline static typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
|
||||||
|
{
|
||||||
return m.norm();
|
return m.norm();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
struct lpNorm_selector<Derived, Infinity> {
|
struct lpNorm_selector<Derived, Infinity>
|
||||||
typedef typename NumTraits<typename traits<Derived>::Scalar>::Real RealScalar;
|
{
|
||||||
EIGEN_DEVICE_FUNC static inline RealScalar run(const MatrixBase<Derived>& m) {
|
inline static typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
|
||||||
if (Derived::SizeAtCompileTime == 0 || (Derived::SizeAtCompileTime == Dynamic && m.size() == 0))
|
{
|
||||||
return RealScalar(0);
|
|
||||||
return m.cwiseAbs().maxCoeff();
|
return m.cwiseAbs().maxCoeff();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
/** \returns the \b coefficient-wise \f$ \ell^p \f$ norm of \c *this, that is, returns the p-th root of the sum of the
|
/** \returns the \f$ \ell^p \f$ norm of *this, that is, returns the p-th root of the sum of the p-th powers of the absolute values
|
||||||
* p-th powers of the absolute values of the coefficients of \c *this. If \a p is the special value \a Eigen::Infinity,
|
* of the coefficients of *this. If \a p is the special value \a Eigen::Infinity, this function returns the \f$ \ell^\infty \f$
|
||||||
* this function returns the \f$ \ell^\infty \f$ norm, that is the maximum of the absolute values of the coefficients of
|
* norm, that is the maximum of the absolute values of the coefficients of *this.
|
||||||
* \c *this.
|
|
||||||
*
|
|
||||||
* In all cases, if \c *this is empty, then the value 0 is returned.
|
|
||||||
*
|
|
||||||
* \note For matrices, this function does not compute the <a
|
|
||||||
* href="https://en.wikipedia.org/wiki/Operator_norm">operator-norm</a>. That is, if \c *this is a matrix, then its
|
|
||||||
* coefficients are interpreted as a 1D vector. Nonetheless, you can easily compute the 1-norm and \f$\infty\f$-norm
|
|
||||||
* matrix operator norms using \link TutorialReductionsVisitorsBroadcastingReductionsNorm partial reductions \endlink.
|
|
||||||
*
|
*
|
||||||
* \sa norm()
|
* \sa norm()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<int p>
|
template<int p>
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
|
||||||
EIGEN_DEVICE_FUNC inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
|
MatrixBase<Derived>::lpNorm() const
|
||||||
#else
|
{
|
||||||
EIGEN_DEVICE_FUNC MatrixBase<Derived>::RealScalar
|
|
||||||
#endif
|
|
||||||
MatrixBase<Derived>::lpNorm() const {
|
|
||||||
return internal::lpNorm_selector<Derived, p>::run(*this);
|
return internal::lpNorm_selector<Derived, p>::run(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,10 +235,12 @@ MatrixBase<Derived>::lpNorm() const {
|
|||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
bool MatrixBase<Derived>::isOrthogonal(const MatrixBase<OtherDerived>& other, const RealScalar& prec) const {
|
bool MatrixBase<Derived>::isOrthogonal
|
||||||
typename internal::nested_eval<Derived, 2>::type nested(derived());
|
(const MatrixBase<OtherDerived>& other, RealScalar prec) const
|
||||||
typename internal::nested_eval<OtherDerived, 2>::type otherNested(other.derived());
|
{
|
||||||
return numext::abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm();
|
typename internal::nested<Derived,2>::type nested(derived());
|
||||||
|
typename internal::nested<OtherDerived,2>::type otherNested(other.derived());
|
||||||
|
return internal::abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns true if *this is approximately an unitary matrix,
|
/** \returns true if *this is approximately an unitary matrix,
|
||||||
@@ -252,16 +255,18 @@ bool MatrixBase<Derived>::isOrthogonal(const MatrixBase<OtherDerived>& other, co
|
|||||||
* Output: \verbinclude MatrixBase_isUnitary.out
|
* Output: \verbinclude MatrixBase_isUnitary.out
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
bool MatrixBase<Derived>::isUnitary(const RealScalar& prec) const {
|
bool MatrixBase<Derived>::isUnitary(RealScalar prec) const
|
||||||
typename internal::nested_eval<Derived, 1>::type self(derived());
|
{
|
||||||
for (Index i = 0; i < cols(); ++i) {
|
typename Derived::Nested nested(derived());
|
||||||
if (!internal::isApprox(self.col(i).squaredNorm(), static_cast<RealScalar>(1), prec)) return false;
|
for(Index i = 0; i < cols(); ++i)
|
||||||
|
{
|
||||||
|
if(!internal::isApprox(nested.col(i).squaredNorm(), static_cast<RealScalar>(1), prec))
|
||||||
|
return false;
|
||||||
for(Index j = 0; j < i; ++j)
|
for(Index j = 0; j < i; ++j)
|
||||||
if (!internal::isMuchSmallerThan(self.col(i).dot(self.col(j)), static_cast<Scalar>(1), prec)) return false;
|
if(!internal::isMuchSmallerThan(nested.col(i).dot(nested.col(j)), static_cast<Scalar>(1), prec))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_DOT_H
|
#endif // EIGEN_DOT_H
|
||||||
|
|||||||
@@ -4,22 +4,30 @@
|
|||||||
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
|
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||||
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#ifndef EIGEN_EIGENBASE_H
|
#ifndef EIGEN_EIGENBASE_H
|
||||||
#define EIGEN_EIGENBASE_H
|
#define EIGEN_EIGENBASE_H
|
||||||
|
|
||||||
// IWYU pragma: private
|
|
||||||
#include "./InternalHeaderCheck.h"
|
|
||||||
|
|
||||||
namespace Eigen {
|
/** Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor MatrixBase(T).
|
||||||
|
|
||||||
/** \class EigenBase
|
|
||||||
* \ingroup Core_Module
|
|
||||||
*
|
|
||||||
* Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor MatrixBase(T).
|
|
||||||
*
|
*
|
||||||
* In other words, an EigenBase object is an object that can be copied into a MatrixBase.
|
* In other words, an EigenBase object is an object that can be copied into a MatrixBase.
|
||||||
*
|
*
|
||||||
@@ -27,51 +35,40 @@ namespace Eigen {
|
|||||||
*
|
*
|
||||||
* Notice that this class is trivial, it is only used to disambiguate overloaded functions.
|
* Notice that this class is trivial, it is only used to disambiguate overloaded functions.
|
||||||
*
|
*
|
||||||
* \sa \blank \ref TopicClassHierarchy
|
* \sa \ref TopicClassHierarchy
|
||||||
*/
|
*/
|
||||||
template <typename Derived>
|
template<typename Derived> struct EigenBase
|
||||||
struct EigenBase {
|
{
|
||||||
// typedef typename internal::plain_matrix_type<Derived>::type PlainObject;
|
// typedef typename internal::plain_matrix_type<Derived>::type PlainObject;
|
||||||
|
|
||||||
/** \brief The interface type of indices
|
|
||||||
* \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE.
|
|
||||||
* \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;
|
|
||||||
|
|
||||||
// FIXME is it needed?
|
|
||||||
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
||||||
|
typedef typename internal::traits<Derived>::Index Index;
|
||||||
|
|
||||||
/** \returns a reference to the derived object */
|
/** \returns a reference to the derived object */
|
||||||
EIGEN_DEVICE_FUNC constexpr Derived& derived() { return *static_cast<Derived*>(this); }
|
Derived& derived() { return *static_cast<Derived*>(this); }
|
||||||
/** \returns a const reference to the derived object */
|
/** \returns a const reference to the derived object */
|
||||||
EIGEN_DEVICE_FUNC constexpr const Derived& derived() const { return *static_cast<const Derived*>(this); }
|
const Derived& derived() const { return *static_cast<const Derived*>(this); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline constexpr Derived& const_cast_derived() const {
|
inline Derived& const_cast_derived() const
|
||||||
return *static_cast<Derived*>(const_cast<EigenBase*>(this));
|
{ return *static_cast<Derived*>(const_cast<EigenBase*>(this)); }
|
||||||
}
|
inline const Derived& const_derived() const
|
||||||
EIGEN_DEVICE_FUNC constexpr inline const Derived& const_derived() const { 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 constexpr Index rows() const 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 constexpr Index cols() const 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 constexpr Index size() const 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> inline void evalTo(Dest& dst) const
|
||||||
EIGEN_DEVICE_FUNC constexpr inline void evalTo(Dest& dst) const {
|
{ derived().evalTo(dst); }
|
||||||
derived().evalTo(dst);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \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> inline void addTo(Dest& dst) const
|
||||||
EIGEN_DEVICE_FUNC constexpr inline void addTo(Dest& dst) const {
|
{
|
||||||
// This is the default implementation,
|
// This is the default implementation,
|
||||||
// derived class can reimplement it in a more optimized way.
|
// derived class can reimplement it in a more optimized way.
|
||||||
typename Dest::PlainObject res(rows(),cols());
|
typename Dest::PlainObject res(rows(),cols());
|
||||||
@@ -80,8 +77,8 @@ struct EigenBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** \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> inline void subTo(Dest& dst) const
|
||||||
EIGEN_DEVICE_FUNC constexpr inline void subTo(Dest& dst) const {
|
{
|
||||||
// This is the default implementation,
|
// This is the default implementation,
|
||||||
// derived class can reimplement it in a more optimized way.
|
// derived class can reimplement it in a more optimized way.
|
||||||
typename Dest::PlainObject res(rows(),cols());
|
typename Dest::PlainObject res(rows(),cols());
|
||||||
@@ -90,25 +87,21 @@ struct EigenBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** \internal Don't use it, but do the equivalent: \code dst.applyOnTheRight(*this); \endcode */
|
/** \internal Don't use it, but do the equivalent: \code dst.applyOnTheRight(*this); \endcode */
|
||||||
template <typename Dest>
|
template<typename Dest> inline void applyThisOnTheRight(Dest& dst) const
|
||||||
EIGEN_DEVICE_FUNC constexpr inline void applyThisOnTheRight(Dest& dst) const {
|
{
|
||||||
// This is the default implementation,
|
// This is the default implementation,
|
||||||
// derived class can reimplement it in a more optimized way.
|
// derived class can reimplement it in a more optimized way.
|
||||||
dst = dst * this->derived();
|
dst = dst * this->derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \internal Don't use it, but do the equivalent: \code dst.applyOnTheLeft(*this); \endcode */
|
/** \internal Don't use it, but do the equivalent: \code dst.applyOnTheLeft(*this); \endcode */
|
||||||
template <typename Dest>
|
template<typename Dest> inline void applyThisOnTheLeft(Dest& dst) const
|
||||||
EIGEN_DEVICE_FUNC constexpr inline void applyThisOnTheLeft(Dest& dst) const {
|
{
|
||||||
// This is the default implementation,
|
// This is the default implementation,
|
||||||
// derived class can reimplement it in a more optimized way.
|
// derived class can reimplement it in a more optimized way.
|
||||||
dst = this->derived() * dst;
|
dst = this->derived() * dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Device>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DeviceWrapper<Derived, Device> device(Device& device);
|
|
||||||
template <typename Device>
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DeviceWrapper<const Derived, Device> device(Device& device) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
@@ -125,25 +118,55 @@ struct EigenBase {
|
|||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC constexpr Derived& DenseBase<Derived>::operator=(const EigenBase<OtherDerived>& other) {
|
Derived& DenseBase<Derived>::operator=(const EigenBase<OtherDerived> &other)
|
||||||
call_assignment(derived(), other.derived());
|
{
|
||||||
|
other.derived().evalTo(derived());
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC constexpr Derived& DenseBase<Derived>::operator+=(const EigenBase<OtherDerived>& other) {
|
Derived& DenseBase<Derived>::operator+=(const EigenBase<OtherDerived> &other)
|
||||||
call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar, typename OtherDerived::Scalar>());
|
{
|
||||||
|
other.derived().addTo(derived());
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC constexpr Derived& DenseBase<Derived>::operator-=(const EigenBase<OtherDerived>& other) {
|
Derived& DenseBase<Derived>::operator-=(const EigenBase<OtherDerived> &other)
|
||||||
call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar, typename OtherDerived::Scalar>());
|
{
|
||||||
|
other.derived().subTo(derived());
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace Eigen
|
/** replaces \c *this by \c *this * \a other.
|
||||||
|
*
|
||||||
|
* \returns a reference to \c *this
|
||||||
|
*/
|
||||||
|
template<typename Derived>
|
||||||
|
template<typename OtherDerived>
|
||||||
|
inline Derived&
|
||||||
|
MatrixBase<Derived>::operator*=(const EigenBase<OtherDerived> &other)
|
||||||
|
{
|
||||||
|
other.derived().applyThisOnTheRight(derived());
|
||||||
|
return derived();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** replaces \c *this by \c *this * \a other. It is equivalent to MatrixBase::operator*=() */
|
||||||
|
template<typename Derived>
|
||||||
|
template<typename OtherDerived>
|
||||||
|
inline void MatrixBase<Derived>::applyOnTheRight(const EigenBase<OtherDerived> &other)
|
||||||
|
{
|
||||||
|
other.derived().applyThisOnTheRight(derived());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** replaces \c *this by \c *this * \a other. */
|
||||||
|
template<typename Derived>
|
||||||
|
template<typename OtherDerived>
|
||||||
|
inline void MatrixBase<Derived>::applyOnTheLeft(const EigenBase<OtherDerived> &other)
|
||||||
|
{
|
||||||
|
other.derived().applyThisOnTheLeft(derived());
|
||||||
|
}
|
||||||
|
|
||||||
#endif // EIGEN_EIGENBASE_H
|
#endif // EIGEN_EIGENBASE_H
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user