Merge branch 'develop' into verdant/smart_ptrs
commit
8e48ccd9cf
|
|
@ -1,4 +1,3 @@
|
||||||
syntax: glob
|
|
||||||
qrc_*cxx
|
qrc_*cxx
|
||||||
*.orig
|
*.orig
|
||||||
*.pyc
|
*.pyc
|
||||||
|
|
@ -13,7 +12,7 @@ core
|
||||||
core.*
|
core.*
|
||||||
*.bak
|
*.bak
|
||||||
*~
|
*~
|
||||||
build*
|
*build*
|
||||||
*.moc.*
|
*.moc.*
|
||||||
*.moc
|
*.moc
|
||||||
ui_*
|
ui_*
|
||||||
|
|
@ -28,7 +27,12 @@ activity.png
|
||||||
*.rej
|
*.rej
|
||||||
log
|
log
|
||||||
patch
|
patch
|
||||||
|
*.patch
|
||||||
a
|
a
|
||||||
a.*
|
a.*
|
||||||
lapack/testing
|
lapack/testing
|
||||||
lapack/reference
|
lapack/reference
|
||||||
|
.*project
|
||||||
|
.settings
|
||||||
|
Makefile
|
||||||
|
!ci/build.gitlab-ci.yml
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
# This file is part of Eigen, a lightweight C++ template library
|
||||||
|
# for linear algebra.
|
||||||
|
#
|
||||||
|
# Copyright (C) 2020 Arm Ltd. and Contributors
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla
|
||||||
|
# Public License v. 2.0. If a copy of the MPL was not distributed
|
||||||
|
# with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- buildsmoketests
|
||||||
|
- smoketests
|
||||||
|
- build
|
||||||
|
- test
|
||||||
|
|
||||||
|
variables:
|
||||||
|
BUILDDIR: builddir
|
||||||
|
EIGEN_CI_CMAKE_GENEATOR: "Ninja"
|
||||||
|
|
||||||
|
include:
|
||||||
|
- "/ci/smoketests.gitlab-ci.yml"
|
||||||
|
- "/ci/build.gitlab-ci.yml"
|
||||||
|
- "/ci/test.gitlab-ci.yml"
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
<!--
|
||||||
|
Please read this!
|
||||||
|
|
||||||
|
Before opening a new issue, make sure to search for keywords in the issues
|
||||||
|
filtered by "bug::confirmed" or "bug::unconfirmed" and "bugzilla" label:
|
||||||
|
|
||||||
|
- https://gitlab.com/libeigen/eigen/-/issues?scope=all&utf8=%E2%9C%93&state=opened&label_name[]=bug%3A%3Aconfirmed
|
||||||
|
- https://gitlab.com/libeigen/eigen/-/issues?scope=all&utf8=%E2%9C%93&state=opened&label_name[]=bug%3A%3Aunconfirmed
|
||||||
|
- https://gitlab.com/libeigen/eigen/-/issues?scope=all&utf8=%E2%9C%93&state=opened&label_name[]=bugzilla
|
||||||
|
|
||||||
|
and verify the issue you're about to submit isn't a duplicate. -->
|
||||||
|
|
||||||
|
### Summary
|
||||||
|
<!-- Summarize the bug encountered concisely. -->
|
||||||
|
|
||||||
|
### Environment
|
||||||
|
<!-- Please provide your development environment here -->
|
||||||
|
- **Operating System** : Windows/Linux
|
||||||
|
- **Architecture** : x64/Arm64/PowerPC ...
|
||||||
|
- **Eigen Version** : 3.3.9
|
||||||
|
- **Compiler Version** : Gcc7.0
|
||||||
|
- **Compile Flags** : -O3 -march=native
|
||||||
|
- **Vector Extension** : SSE/AVX/NEON ...
|
||||||
|
|
||||||
|
### Minimal Example
|
||||||
|
<!-- If possible, please create a minimal example here that exhibits the problematic behavior.
|
||||||
|
You can also link to [godbolt](https://godbolt.org). But please note that you need to click
|
||||||
|
the "Share" button in the top right-hand corner of the godbolt page where you reproduce the sample
|
||||||
|
code to get the share link instead of in your browser address bar.
|
||||||
|
|
||||||
|
You can read [the guidelines on stackoverflow](https://stackoverflow.com/help/minimal-reproducible-example)
|
||||||
|
on how to create a good minimal example. -->
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
//show your code here
|
||||||
|
```
|
||||||
|
|
||||||
|
### Steps to reproduce
|
||||||
|
<!-- Describe how one can reproduce the issue - this is very important. Please use an ordered list. -->
|
||||||
|
|
||||||
|
1. first step
|
||||||
|
2. second step
|
||||||
|
3. ...
|
||||||
|
|
||||||
|
### What is the current *bug* behavior?
|
||||||
|
<!-- Describe what actually happens. -->
|
||||||
|
|
||||||
|
### What is the expected *correct* behavior?
|
||||||
|
<!-- Describe what you should see instead. -->
|
||||||
|
|
||||||
|
### Relevant logs
|
||||||
|
<!-- Add relevant code snippets or program output within blocks marked by " ``` " -->
|
||||||
|
|
||||||
|
<!-- OPTIONAL: remove this section if you are not reporting a compilation warning issue.-->
|
||||||
|
### Warning Messages
|
||||||
|
<!-- Show us the warning messages you got! -->
|
||||||
|
|
||||||
|
<!-- OPTIONAL: remove this section if you are not reporting a performance issue. -->
|
||||||
|
### Benchmark scripts and results
|
||||||
|
<!-- Please share any benchmark scripts - either standalone, or using [Google Benchmark](https://github.com/google/benchmark). -->
|
||||||
|
|
||||||
|
### Anything else that might help
|
||||||
|
<!-- It will be better to provide us more information to help narrow down the cause.
|
||||||
|
Including but not limited to the following:
|
||||||
|
- lines of code that might help us diagnose the problem.
|
||||||
|
- potential ways to address the issue.
|
||||||
|
- last known working/first broken version (release number or commit hash). -->
|
||||||
|
|
||||||
|
- [ ] Have a plan to fix this issue.
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
### Describe the feature you would like to be implemented.
|
||||||
|
|
||||||
|
### Would such a feature be useful for other users? Why?
|
||||||
|
|
||||||
|
### Any hints on how to implement the requested feature?
|
||||||
|
|
||||||
|
### Additional resources
|
||||||
26
gtsam/3rdparty/Eigen/.gitlab/merge_request_templates/Merge Request Template.md
vendored
Normal file
26
gtsam/3rdparty/Eigen/.gitlab/merge_request_templates/Merge Request Template.md
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
<!--
|
||||||
|
Thanks for contributing a merge request! Please name and fully describe your MR as you would for a commit message.
|
||||||
|
If the MR fixes an issue, please include "Fixes #issue" in the commit message and the MR description.
|
||||||
|
|
||||||
|
In addition, we recommend that first-time contributors read our [contribution guidelines](https://eigen.tuxfamily.org/index.php?title=Contributing_to_Eigen) and [git page](https://eigen.tuxfamily.org/index.php?title=Git), which will help you submit a more standardized MR.
|
||||||
|
|
||||||
|
Before submitting the MR, you also need to complete the following checks:
|
||||||
|
- Make one PR per feature/bugfix (don't mix multiple changes into one PR). Avoid committing unrelated changes.
|
||||||
|
- Rebase before committing
|
||||||
|
- For code changes, run the test suite (at least the tests that are likely affected by the change).
|
||||||
|
See our [test guidelines](https://eigen.tuxfamily.org/index.php?title=Tests).
|
||||||
|
- If possible, add a test (both for bug-fixes as well as new features)
|
||||||
|
- Make sure new features are documented
|
||||||
|
|
||||||
|
Note that we are a team of volunteers; we appreciate your patience during the review process.
|
||||||
|
|
||||||
|
Again, thanks for contributing! -->
|
||||||
|
|
||||||
|
### Reference issue
|
||||||
|
<!-- You can link to a specific issue using the gitlab syntax #<issue number> -->
|
||||||
|
|
||||||
|
### What does this implement/fix?
|
||||||
|
<!--Please explain your changes.-->
|
||||||
|
|
||||||
|
### Additional information
|
||||||
|
<!--Any additional information you think is important.-->
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
2db9468678c6480c9633b6272ff0e3599d1e11a3 2.0-beta3
|
|
||||||
375224817dce669b6fa31d920d4c895a63fabf32 2.0-beta1
|
|
||||||
3b8120f077865e2a072e10f5be33e1d942b83a06 2.0-rc1
|
|
||||||
19dfc0e7666bcee26f7a49eb42f39a0280a3485e 2.0-beta5
|
|
||||||
7a7d8a9526f003ffa2430dfb0c2c535b5add3023 2.0-beta4
|
|
||||||
7d14ad088ac23769c349518762704f0257f6a39b 2.0.1
|
|
||||||
b9d48561579fd7d4c05b2aa42235dc9de6484bf2 2.0-beta6
|
|
||||||
e17630a40408243cb1a51ad0fe3a99beb75b7450 before-hg-migration
|
|
||||||
eda654d4cda2210ce80719addcf854773e6dec5a 2.0.0
|
|
||||||
ee9a7c468a9e73fab12f38f02bac24b07f29ed71 2.0-beta2
|
|
||||||
d49097c25d8049e730c254a2fed725a240ce4858 after-hg-migration
|
|
||||||
655348878731bcb5d9bbe0854077b052e75e5237 actual-start-from-scratch
|
|
||||||
12a658962d4e6dfdc9a1c350fe7b69e36e70675c 3.0-beta1
|
|
||||||
5c4180ad827b3f869b13b1d82f5a6ce617d6fcee 3.0-beta2
|
|
||||||
7ae24ca6f3891d5ac58ddc7db60ad413c8d6ec35 3.0-beta3
|
|
||||||
c40708b9088d622567fecc9208ad4a426621d364 3.0-beta4
|
|
||||||
b6456624eae74f49ae8683d8e7b2882a2ca0342a 3.0-rc1
|
|
||||||
a810d5dbab47acfe65b3350236efdd98f67d4d8a 3.1.0-alpha1
|
|
||||||
304c88ca3affc16dd0b008b1104873986edd77af 3.1.0-alpha2
|
|
||||||
920fc730b5930daae0a6dbe296d60ce2e3808215 3.1.0-beta1
|
|
||||||
8383e883ebcc6f14695ff0b5e20bb631abab43fb 3.1.0-rc1
|
|
||||||
bf4cb8c934fa3a79f45f1e629610f0225e93e493 3.1.0-rc2
|
|
||||||
da195914abcc1d739027cbee7c52077aab30b336 3.2-beta1
|
|
||||||
a8e0d153fc5e239ef8b06e3665f1f9e8cb8d49c8 before-evaluators
|
|
||||||
09a8e21866106b49c5dec1d6d543e5794e82efa0 3.3-alpha1
|
|
||||||
ce5a455b34c0a0ac3545a1497cb4a16c38ed90e8 3.3-beta1
|
|
||||||
69d418c0699907bcd0bf9e0b3ba0a112ed091d85 3.3-beta2
|
|
||||||
bef509908b9da05d0d07ffc0da105e2c8c6d3996 3.3-rc1
|
|
||||||
04ab5fa4b241754afcf631117572276444c67239 3.3-rc2
|
|
||||||
26667be4f70baf4f0d39e96f330714c87b399090 3.3.0
|
|
||||||
f562a193118d4f40514e2f4a0ace6e974926ef06 3.3.1
|
|
||||||
da9b4e14c2550e0d11078a3c39e6d56eba9905df 3.3.2
|
|
||||||
67e894c6cd8f5f1f604b27d37ed47fdf012674ff 3.3.3
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
project(Eigen3)
|
# cmake_minimum_require must be the first command of the file
|
||||||
|
cmake_minimum_required(VERSION 3.5.0)
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 2.8.5)
|
project(Eigen3)
|
||||||
|
|
||||||
# guard against in-source builds
|
# guard against in-source builds
|
||||||
|
|
||||||
|
|
@ -8,6 +9,7 @@ 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()
|
||||||
|
|
||||||
|
|
||||||
# Alias Eigen_*_DIR to Eigen3_*_DIR:
|
# Alias Eigen_*_DIR to Eigen3_*_DIR:
|
||||||
|
|
||||||
set(Eigen_SOURCE_DIR ${Eigen3_SOURCE_DIR})
|
set(Eigen_SOURCE_DIR ${Eigen3_SOURCE_DIR})
|
||||||
|
|
@ -19,16 +21,9 @@ if (NOT CMAKE_BUILD_TYPE)
|
||||||
set(CMAKE_BUILD_TYPE "Release")
|
set(CMAKE_BUILD_TYPE "Release")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
string(TOLOWER "${CMAKE_BUILD_TYPE}" cmake_build_type_tolower)
|
|
||||||
if( NOT cmake_build_type_tolower STREQUAL "debug"
|
|
||||||
AND NOT cmake_build_type_tolower STREQUAL "release"
|
|
||||||
AND NOT cmake_build_type_tolower STREQUAL "relwithdebinfo")
|
|
||||||
message(FATAL_ERROR "Unknown build type \"${CMAKE_BUILD_TYPE}\". Allowed values are Debug, Release, RelWithDebInfo (case-insensitive).")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
#############################################################################
|
#############################################################################
|
||||||
# retrieve version infomation #
|
# retrieve version information #
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
# automatically parse the version number
|
# automatically parse the version number
|
||||||
|
|
@ -41,29 +36,28 @@ string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen_minor_
|
||||||
set(EIGEN_MINOR_VERSION "${CMAKE_MATCH_1}")
|
set(EIGEN_MINOR_VERSION "${CMAKE_MATCH_1}")
|
||||||
set(EIGEN_VERSION_NUMBER ${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION})
|
set(EIGEN_VERSION_NUMBER ${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION})
|
||||||
|
|
||||||
# if we are not in a mercurial clone
|
# if we are not in a git clone
|
||||||
if(IS_DIRECTORY ${CMAKE_SOURCE_DIR}/.hg)
|
if(IS_DIRECTORY ${CMAKE_SOURCE_DIR}/.git)
|
||||||
# if the mercurial program is absent or this will leave the EIGEN_HG_CHANGESET string empty,
|
# if the git program is absent or this will leave the EIGEN_GIT_REVNUM string empty,
|
||||||
# but won't stop CMake.
|
# but won't stop CMake.
|
||||||
execute_process(COMMAND hg tip -R ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE EIGEN_HGTIP_OUTPUT)
|
execute_process(COMMAND git ls-remote --refs -q ${CMAKE_SOURCE_DIR} HEAD OUTPUT_VARIABLE EIGEN_GIT_OUTPUT)
|
||||||
execute_process(COMMAND hg branch -R ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE EIGEN_BRANCH_OUTPUT)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# if this is the default (aka development) branch, extract the mercurial changeset number from the hg tip output...
|
# extract the git rev number from the git output...
|
||||||
if(EIGEN_BRANCH_OUTPUT MATCHES "default")
|
if(EIGEN_GIT_OUTPUT)
|
||||||
string(REGEX MATCH "^changeset: *[0-9]*:([0-9;a-f]+).*" EIGEN_HG_CHANGESET_MATCH "${EIGEN_HGTIP_OUTPUT}")
|
string(REGEX MATCH "^([0-9;a-f]+).*" EIGEN_GIT_CHANGESET_MATCH "${EIGEN_GIT_OUTPUT}")
|
||||||
set(EIGEN_HG_CHANGESET "${CMAKE_MATCH_1}")
|
set(EIGEN_GIT_REVNUM "${CMAKE_MATCH_1}")
|
||||||
endif(EIGEN_BRANCH_OUTPUT MATCHES "default")
|
endif()
|
||||||
#...and show it next to the version number
|
#...and show it next to the version number
|
||||||
if(EIGEN_HG_CHANGESET)
|
if(EIGEN_GIT_REVNUM)
|
||||||
set(EIGEN_VERSION "${EIGEN_VERSION_NUMBER} (mercurial changeset ${EIGEN_HG_CHANGESET})")
|
set(EIGEN_VERSION "${EIGEN_VERSION_NUMBER} (git rev ${EIGEN_GIT_REVNUM})")
|
||||||
else(EIGEN_HG_CHANGESET)
|
else()
|
||||||
set(EIGEN_VERSION "${EIGEN_VERSION_NUMBER}")
|
set(EIGEN_VERSION "${EIGEN_VERSION_NUMBER}")
|
||||||
endif(EIGEN_HG_CHANGESET)
|
endif()
|
||||||
|
|
||||||
|
|
||||||
include(CheckCXXCompilerFlag)
|
include(CheckCXXCompilerFlag)
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
include(CMakeDependentOption)
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
||||||
|
|
||||||
|
|
@ -78,7 +72,7 @@ macro(ei_add_cxx_compiler_flag FLAG)
|
||||||
if(COMPILER_SUPPORT_${SFLAG})
|
if(COMPILER_SUPPORT_${SFLAG})
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAG}")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAG}")
|
||||||
endif()
|
endif()
|
||||||
endmacro(ei_add_cxx_compiler_flag)
|
endmacro()
|
||||||
|
|
||||||
check_cxx_compiler_flag("-std=c++11" EIGEN_COMPILER_SUPPORT_CPP11)
|
check_cxx_compiler_flag("-std=c++11" EIGEN_COMPILER_SUPPORT_CPP11)
|
||||||
|
|
||||||
|
|
@ -94,6 +88,9 @@ else()
|
||||||
ei_add_cxx_compiler_flag("-std=c++03")
|
ei_add_cxx_compiler_flag("-std=c++03")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Determine if we should build shared libraries on this platform.
|
||||||
|
get_cmake_property(EIGEN_BUILD_SHARED_LIBS TARGET_SUPPORTS_SHARED_LIBS)
|
||||||
|
|
||||||
#############################################################################
|
#############################################################################
|
||||||
# find how to link to the standard libraries #
|
# find how to link to the standard libraries #
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
@ -134,7 +131,7 @@ if(NOT WIN32 OR NOT CMAKE_HOST_SYSTEM_NAME MATCHES Windows)
|
||||||
option(EIGEN_BUILD_PKGCONFIG "Build pkg-config .pc file for Eigen" ON)
|
option(EIGEN_BUILD_PKGCONFIG "Build pkg-config .pc file for Eigen" ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
set(CMAKE_INCLUDE_CURRENT_DIR OFF)
|
||||||
|
|
||||||
option(EIGEN_SPLIT_LARGE_TESTS "Split large tests into smaller executables" ON)
|
option(EIGEN_SPLIT_LARGE_TESTS "Split large tests into smaller executables" ON)
|
||||||
|
|
||||||
|
|
@ -174,11 +171,7 @@ if(NOT MSVC)
|
||||||
ei_add_cxx_compiler_flag("-Wdouble-promotion")
|
ei_add_cxx_compiler_flag("-Wdouble-promotion")
|
||||||
# ei_add_cxx_compiler_flag("-Wconversion")
|
# ei_add_cxx_compiler_flag("-Wconversion")
|
||||||
|
|
||||||
# -Wshadow is insanely too strict with gcc, hopefully it will become usable with gcc 6
|
|
||||||
# if(NOT CMAKE_COMPILER_IS_GNUCXX OR (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "5.0.0"))
|
|
||||||
if(NOT CMAKE_COMPILER_IS_GNUCXX)
|
|
||||||
ei_add_cxx_compiler_flag("-Wshadow")
|
ei_add_cxx_compiler_flag("-Wshadow")
|
||||||
endif()
|
|
||||||
|
|
||||||
ei_add_cxx_compiler_flag("-Wno-psabi")
|
ei_add_cxx_compiler_flag("-Wno-psabi")
|
||||||
ei_add_cxx_compiler_flag("-Wno-variadic-macros")
|
ei_add_cxx_compiler_flag("-Wno-variadic-macros")
|
||||||
|
|
@ -251,12 +244,30 @@ if(NOT MSVC)
|
||||||
message(STATUS "Enabling FMA in tests/examples")
|
message(STATUS "Enabling FMA in tests/examples")
|
||||||
endif()
|
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)
|
option(EIGEN_TEST_AVX512 "Enable/Disable AVX512 in tests/examples" OFF)
|
||||||
if(EIGEN_TEST_AVX512)
|
if(EIGEN_TEST_AVX512)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx512f -fabi-version=6 -DEIGEN_ENABLE_AVX512")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx512f -mfma")
|
||||||
|
if (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fabi-version=6")
|
||||||
|
endif()
|
||||||
message(STATUS "Enabling AVX512 in tests/examples")
|
message(STATUS "Enabling AVX512 in tests/examples")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
option(EIGEN_TEST_AVX512DQ "Enable/Disable AVX512DQ in tests/examples" OFF)
|
||||||
|
if(EIGEN_TEST_AVX512DQ)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx512dq")
|
||||||
|
if (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fabi-version=6")
|
||||||
|
endif()
|
||||||
|
message(STATUS "Enabling AVX512DQ in tests/examples")
|
||||||
|
endif()
|
||||||
|
|
||||||
option(EIGEN_TEST_F16C "Enable/Disable F16C in tests/examples" OFF)
|
option(EIGEN_TEST_F16C "Enable/Disable F16C in tests/examples" OFF)
|
||||||
if(EIGEN_TEST_F16C)
|
if(EIGEN_TEST_F16C)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mf16c")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mf16c")
|
||||||
|
|
@ -275,6 +286,12 @@ if(NOT MSVC)
|
||||||
message(STATUS "Enabling VSX in tests/examples")
|
message(STATUS "Enabling VSX in tests/examples")
|
||||||
endif()
|
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_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)
|
if(EIGEN_TEST_FMA)
|
||||||
|
|
@ -292,12 +309,18 @@ if(NOT MSVC)
|
||||||
message(STATUS "Enabling NEON in tests/examples")
|
message(STATUS "Enabling NEON in tests/examples")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
option(EIGEN_TEST_ZVECTOR "Enable/Disable S390X(zEC13) ZVECTOR in tests/examples" OFF)
|
option(EIGEN_TEST_Z13 "Enable/Disable S390X(zEC13) ZVECTOR in tests/examples" OFF)
|
||||||
if(EIGEN_TEST_ZVECTOR)
|
if(EIGEN_TEST_Z13)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=z13 -mzvector")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=z13 -mzvector")
|
||||||
message(STATUS "Enabling S390X(zEC13) ZVECTOR in tests/examples")
|
message(STATUS "Enabling S390X(zEC13) ZVECTOR in tests/examples")
|
||||||
endif()
|
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)
|
||||||
|
|
@ -307,7 +330,7 @@ if(NOT MSVC)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
else(NOT MSVC)
|
else()
|
||||||
|
|
||||||
# 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)
|
||||||
|
|
@ -315,7 +338,7 @@ else(NOT MSVC)
|
||||||
# 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 deactive selectively)
|
# C4505 - unreferenced local function has been removed (impossible to deactivate 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
|
||||||
|
|
@ -335,10 +358,23 @@ else(NOT MSVC)
|
||||||
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(NOT CMAKE_CL_64)
|
endif()
|
||||||
message(STATUS "Enabling SSE2 in tests/examples")
|
message(STATUS "Enabling SSE2 in tests/examples")
|
||||||
endif(EIGEN_TEST_SSE2)
|
endif()
|
||||||
endif(NOT 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)
|
||||||
|
if(EIGEN_TEST_FMA AND NOT EIGEN_TEST_NEON)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:AVX2")
|
||||||
|
message(STATUS "Enabling FMA/AVX2 in tests/examples")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
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)
|
||||||
|
|
@ -382,7 +418,7 @@ endif()
|
||||||
|
|
||||||
set(EIGEN_CUDA_COMPUTE_ARCH 30 CACHE STRING "The CUDA compute architecture level to target when compiling CUDA code")
|
set(EIGEN_CUDA_COMPUTE_ARCH 30 CACHE STRING "The CUDA compute architecture level to target when compiling CUDA code")
|
||||||
|
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
# Backward compatibility support for EIGEN_INCLUDE_INSTALL_DIR
|
# Backward compatibility support for EIGEN_INCLUDE_INSTALL_DIR
|
||||||
if(EIGEN_INCLUDE_INSTALL_DIR)
|
if(EIGEN_INCLUDE_INSTALL_DIR)
|
||||||
|
|
@ -391,22 +427,28 @@ endif()
|
||||||
|
|
||||||
if(EIGEN_INCLUDE_INSTALL_DIR AND NOT INCLUDE_INSTALL_DIR)
|
if(EIGEN_INCLUDE_INSTALL_DIR AND NOT INCLUDE_INSTALL_DIR)
|
||||||
set(INCLUDE_INSTALL_DIR ${EIGEN_INCLUDE_INSTALL_DIR}
|
set(INCLUDE_INSTALL_DIR ${EIGEN_INCLUDE_INSTALL_DIR}
|
||||||
CACHE PATH "The directory relative to CMAKE_PREFIX_PATH where Eigen header files are installed")
|
CACHE PATH "The directory relative to CMAKE_INSTALL_PREFIX where Eigen header files are installed")
|
||||||
else()
|
else()
|
||||||
set(INCLUDE_INSTALL_DIR
|
set(INCLUDE_INSTALL_DIR
|
||||||
"${CMAKE_INSTALL_INCLUDEDIR}/eigen3"
|
"${CMAKE_INSTALL_INCLUDEDIR}/eigen3"
|
||||||
CACHE PATH "The directory relative to CMAKE_PREFIX_PATH where Eigen header files are installed"
|
CACHE PATH "The directory relative to CMAKE_INSTALL_PREFIX where Eigen header files are installed"
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
set(CMAKEPACKAGE_INSTALL_DIR
|
set(CMAKEPACKAGE_INSTALL_DIR
|
||||||
"${CMAKE_INSTALL_DATADIR}/eigen3/cmake"
|
"${CMAKE_INSTALL_DATADIR}/eigen3/cmake"
|
||||||
CACHE PATH "The directory relative to CMAKE_PREFIX_PATH where Eigen3Config.cmake is installed"
|
CACHE PATH "The directory relative to CMAKE_INSTALL_PREFIX where Eigen3Config.cmake is installed"
|
||||||
)
|
)
|
||||||
set(PKGCONFIG_INSTALL_DIR
|
set(PKGCONFIG_INSTALL_DIR
|
||||||
"${CMAKE_INSTALL_DATADIR}/pkgconfig"
|
"${CMAKE_INSTALL_DATADIR}/pkgconfig"
|
||||||
CACHE PATH "The directory relative to CMAKE_PREFIX_PATH where eigen3.pc is installed"
|
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()
|
||||||
|
|
||||||
# similar to set_target_properties but append the property instead of overwriting it
|
# similar to set_target_properties but append the property instead of overwriting it
|
||||||
macro(ei_add_target_property target prop value)
|
macro(ei_add_target_property target prop value)
|
||||||
|
|
@ -415,9 +457,9 @@ macro(ei_add_target_property target prop value)
|
||||||
# if the property wasn't previously set, ${previous} is now "previous-NOTFOUND" which cmake allows catching with plain if()
|
# if the property wasn't previously set, ${previous} is now "previous-NOTFOUND" which cmake allows catching with plain if()
|
||||||
if(NOT previous)
|
if(NOT previous)
|
||||||
set(previous "")
|
set(previous "")
|
||||||
endif(NOT previous)
|
endif()
|
||||||
set_target_properties(${target} PROPERTIES ${prop} "${previous} ${value}")
|
set_target_properties(${target} PROPERTIES ${prop} "${previous} ${value}")
|
||||||
endmacro(ei_add_target_property)
|
endmacro()
|
||||||
|
|
||||||
install(FILES
|
install(FILES
|
||||||
signature_of_eigen3_matrix_library
|
signature_of_eigen3_matrix_library
|
||||||
|
|
@ -431,9 +473,14 @@ if(EIGEN_BUILD_PKGCONFIG)
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_subdirectory(Eigen)
|
install(DIRECTORY Eigen DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel)
|
||||||
|
|
||||||
|
|
||||||
|
option(EIGEN_BUILD_DOC "Enable creation of Eigen documentation" ON)
|
||||||
|
if(EIGEN_BUILD_DOC)
|
||||||
add_subdirectory(doc EXCLUDE_FROM_ALL)
|
add_subdirectory(doc EXCLUDE_FROM_ALL)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
option(BUILD_TESTING "Enable creation of Eigen tests." ON)
|
option(BUILD_TESTING "Enable creation of Eigen tests." ON)
|
||||||
if(BUILD_TESTING)
|
if(BUILD_TESTING)
|
||||||
|
|
@ -444,6 +491,8 @@ if(BUILD_TESTING)
|
||||||
else()
|
else()
|
||||||
add_subdirectory(test EXCLUDE_FROM_ALL)
|
add_subdirectory(test EXCLUDE_FROM_ALL)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(failtest)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)
|
if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)
|
||||||
|
|
@ -456,9 +505,32 @@ endif()
|
||||||
|
|
||||||
# add SYCL
|
# add SYCL
|
||||||
option(EIGEN_TEST_SYCL "Add Sycl support." OFF)
|
option(EIGEN_TEST_SYCL "Add Sycl support." OFF)
|
||||||
|
option(EIGEN_SYCL_TRISYCL "Use the triSYCL Sycl implementation (ComputeCPP by default)." OFF)
|
||||||
if(EIGEN_TEST_SYCL)
|
if(EIGEN_TEST_SYCL)
|
||||||
set (CMAKE_MODULE_PATH "${CMAKE_ROOT}/Modules" "cmake/Modules/" "${CMAKE_MODULE_PATH}")
|
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)
|
||||||
|
else()
|
||||||
|
message(STATUS "Using ComputeCPP SYCL")
|
||||||
include(FindComputeCpp)
|
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}
|
||||||
|
)
|
||||||
|
endif(EIGEN_SYCL_TRISYCL)
|
||||||
|
option(EIGEN_DONT_VECTORIZE_SYCL "Don't use vectorisation in the SYCL tests." OFF)
|
||||||
|
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()
|
||||||
|
|
||||||
add_subdirectory(unsupported)
|
add_subdirectory(unsupported)
|
||||||
|
|
@ -471,11 +543,11 @@ add_subdirectory(scripts EXCLUDE_FROM_ALL)
|
||||||
# TODO: consider also replacing EIGEN_BUILD_BTL by a custom target "make btl"?
|
# TODO: consider also replacing EIGEN_BUILD_BTL by a custom target "make btl"?
|
||||||
if(EIGEN_BUILD_BTL)
|
if(EIGEN_BUILD_BTL)
|
||||||
add_subdirectory(bench/btl EXCLUDE_FROM_ALL)
|
add_subdirectory(bench/btl EXCLUDE_FROM_ALL)
|
||||||
endif(EIGEN_BUILD_BTL)
|
endif()
|
||||||
|
|
||||||
if(NOT WIN32)
|
if(NOT WIN32)
|
||||||
add_subdirectory(bench/spbench EXCLUDE_FROM_ALL)
|
add_subdirectory(bench/spbench EXCLUDE_FROM_ALL)
|
||||||
endif(NOT WIN32)
|
endif()
|
||||||
|
|
||||||
configure_file(scripts/cdashtesting.cmake.in cdashtesting.cmake @ONLY)
|
configure_file(scripts/cdashtesting.cmake.in cdashtesting.cmake @ONLY)
|
||||||
|
|
||||||
|
|
@ -487,18 +559,16 @@ message(STATUS "")
|
||||||
message(STATUS "Configured Eigen ${EIGEN_VERSION_NUMBER}")
|
message(STATUS "Configured Eigen ${EIGEN_VERSION_NUMBER}")
|
||||||
message(STATUS "")
|
message(STATUS "")
|
||||||
|
|
||||||
option(EIGEN_FAILTEST "Enable failtests." OFF)
|
|
||||||
if(EIGEN_FAILTEST)
|
|
||||||
add_subdirectory(failtest)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
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 "Some things you can do now:")
|
message(STATUS "Available targets (use: make TARGET):")
|
||||||
message(STATUS "--------------+--------------------------------------------------------------")
|
else()
|
||||||
message(STATUS "Command | Description")
|
message(STATUS "Available targets (use: cmake --build . --target TARGET):")
|
||||||
message(STATUS "--------------+--------------------------------------------------------------")
|
endif()
|
||||||
message(STATUS "make install | Install Eigen. Headers will be installed to:")
|
message(STATUS "---------+--------------------------------------------------------------")
|
||||||
|
message(STATUS "Target | Description")
|
||||||
|
message(STATUS "---------+--------------------------------------------------------------")
|
||||||
|
message(STATUS "install | Install Eigen. Headers will be installed to:")
|
||||||
message(STATUS " | <CMAKE_INSTALL_PREFIX>/<INCLUDE_INSTALL_DIR>")
|
message(STATUS " | <CMAKE_INSTALL_PREFIX>/<INCLUDE_INSTALL_DIR>")
|
||||||
message(STATUS " | Using the following values:")
|
message(STATUS " | Using the following values:")
|
||||||
message(STATUS " | CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")
|
message(STATUS " | CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")
|
||||||
|
|
@ -507,17 +577,14 @@ if(cmake_generator_tolower MATCHES "makefile")
|
||||||
message(STATUS " | cmake . -DCMAKE_INSTALL_PREFIX=yourprefix")
|
message(STATUS " | cmake . -DCMAKE_INSTALL_PREFIX=yourprefix")
|
||||||
message(STATUS " | Or:")
|
message(STATUS " | Or:")
|
||||||
message(STATUS " | cmake . -DINCLUDE_INSTALL_DIR=yourdir")
|
message(STATUS " | cmake . -DINCLUDE_INSTALL_DIR=yourdir")
|
||||||
message(STATUS "make doc | Generate the API documentation, requires Doxygen & LaTeX")
|
message(STATUS "doc | Generate the API documentation, requires Doxygen & LaTeX")
|
||||||
message(STATUS "make check | Build and run the unit-tests. Read this page:")
|
if(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")
|
||||||
message(STATUS "make blas | Build BLAS library (not the same thing as Eigen)")
|
|
||||||
message(STATUS "make uninstall| Removes files installed by make install")
|
|
||||||
message(STATUS "--------------+--------------------------------------------------------------")
|
|
||||||
else()
|
|
||||||
message(STATUS "To build/run the unit tests, read this page:")
|
|
||||||
message(STATUS " http://eigen.tuxfamily.org/index.php?title=Tests")
|
|
||||||
endif()
|
endif()
|
||||||
|
message(STATUS "blas | Build BLAS library (not the same thing as Eigen)")
|
||||||
|
message(STATUS "uninstall| Remove files installed by the install target")
|
||||||
|
message(STATUS "---------+--------------------------------------------------------------")
|
||||||
message(STATUS "")
|
message(STATUS "")
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -529,13 +596,11 @@ set ( EIGEN_DEFINITIONS "")
|
||||||
set ( EIGEN_INCLUDE_DIR "${CMAKE_INSTALL_PREFIX}/${INCLUDE_INSTALL_DIR}" )
|
set ( EIGEN_INCLUDE_DIR "${CMAKE_INSTALL_PREFIX}/${INCLUDE_INSTALL_DIR}" )
|
||||||
set ( EIGEN_ROOT_DIR ${CMAKE_INSTALL_PREFIX} )
|
set ( EIGEN_ROOT_DIR ${CMAKE_INSTALL_PREFIX} )
|
||||||
|
|
||||||
# Interface libraries require at least CMake 3.0
|
|
||||||
if (NOT CMAKE_VERSION VERSION_LESS 3.0)
|
|
||||||
include (CMakePackageConfigHelpers)
|
include (CMakePackageConfigHelpers)
|
||||||
|
|
||||||
# Imported target support
|
# Imported target support
|
||||||
add_library (eigen INTERFACE)
|
add_library (eigen INTERFACE)
|
||||||
|
add_library (Eigen3::Eigen ALIAS eigen)
|
||||||
target_compile_definitions (eigen INTERFACE ${EIGEN_DEFINITIONS})
|
target_compile_definitions (eigen INTERFACE ${EIGEN_DEFINITIONS})
|
||||||
target_include_directories (eigen INTERFACE
|
target_include_directories (eigen INTERFACE
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||||
|
|
@ -574,38 +639,6 @@ if (NOT CMAKE_VERSION VERSION_LESS 3.0)
|
||||||
|
|
||||||
install (EXPORT Eigen3Targets NAMESPACE Eigen3:: DESTINATION ${CMAKEPACKAGE_INSTALL_DIR})
|
install (EXPORT Eigen3Targets NAMESPACE Eigen3:: DESTINATION ${CMAKEPACKAGE_INSTALL_DIR})
|
||||||
|
|
||||||
else (NOT CMAKE_VERSION VERSION_LESS 3.0)
|
|
||||||
# Fallback to legacy Eigen3Config.cmake without the imported target
|
|
||||||
|
|
||||||
# If CMakePackageConfigHelpers module is available (CMake >= 2.8.8)
|
|
||||||
# create a relocatable Config file, otherwise leave the hardcoded paths
|
|
||||||
include(CMakePackageConfigHelpers OPTIONAL RESULT_VARIABLE CPCH_PATH)
|
|
||||||
|
|
||||||
if(CPCH_PATH)
|
|
||||||
configure_package_config_file (
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/cmake/Eigen3ConfigLegacy.cmake.in
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/Eigen3Config.cmake
|
|
||||||
PATH_VARS EIGEN_INCLUDE_DIR EIGEN_ROOT_DIR
|
|
||||||
INSTALL_DESTINATION ${CMAKEPACKAGE_INSTALL_DIR}
|
|
||||||
NO_CHECK_REQUIRED_COMPONENTS_MACRO # Eigen does not provide components
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
# The PACKAGE_* variables are defined by the configure_package_config_file
|
|
||||||
# but without it we define them manually to the hardcoded paths
|
|
||||||
set(PACKAGE_INIT "")
|
|
||||||
set(PACKAGE_EIGEN_INCLUDE_DIR ${EIGEN_INCLUDE_DIR})
|
|
||||||
set(PACKAGE_EIGEN_ROOT_DIR ${EIGEN_ROOT_DIR})
|
|
||||||
configure_file ( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Eigen3ConfigLegacy.cmake.in
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/Eigen3Config.cmake
|
|
||||||
@ONLY ESCAPE_QUOTES )
|
|
||||||
endif()
|
|
||||||
|
|
||||||
write_basic_package_version_file( Eigen3ConfigVersion.cmake
|
|
||||||
VERSION ${EIGEN_VERSION_NUMBER}
|
|
||||||
COMPATIBILITY SameMajorVersion )
|
|
||||||
|
|
||||||
endif (NOT CMAKE_VERSION VERSION_LESS 3.0)
|
|
||||||
|
|
||||||
install ( FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/UseEigen3.cmake
|
install ( FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/UseEigen3.cmake
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/Eigen3Config.cmake
|
${CMAKE_CURRENT_BINARY_DIR}/Eigen3Config.cmake
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/Eigen3ConfigVersion.cmake
|
${CMAKE_CURRENT_BINARY_DIR}/Eigen3ConfigVersion.cmake
|
||||||
|
|
@ -614,3 +647,7 @@ install ( FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/UseEigen3.cmake
|
||||||
# Add uninstall target
|
# Add uninstall target
|
||||||
add_custom_target ( uninstall
|
add_custom_target ( uninstall
|
||||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/EigenUninstall.cmake)
|
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/EigenUninstall.cmake)
|
||||||
|
|
||||||
|
if (EIGEN_SPLIT_TESTSUITE)
|
||||||
|
ei_split_testsuite("${EIGEN_SPLIT_TESTSUITE}")
|
||||||
|
endif()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,203 @@
|
||||||
|
/*
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
@ -49,4 +49,3 @@ SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT
|
||||||
(INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE,
|
(INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE,
|
||||||
EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE
|
EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE
|
||||||
POSSIBILITY OF SUCH LOSS OR DAMAGES.
|
POSSIBILITY OF SUCH LOSS OR DAMAGES.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,16 @@
|
||||||
## 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 3.3")
|
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 "manao.inria.fr")
|
set(CTEST_DROP_SITE "my.cdash.org")
|
||||||
set(CTEST_DROP_LOCATION "/CDash/submit.php?project=Eigen+3.3")
|
set(CTEST_DROP_LOCATION "/submit.php?project=Eigen")
|
||||||
set(CTEST_DROP_SITE_CDASH TRUE)
|
set(CTEST_DROP_SITE_CDASH TRUE)
|
||||||
|
#set(CTEST_PROJECT_SUBPROJECTS
|
||||||
|
#Official
|
||||||
|
#Unsupported
|
||||||
|
#)
|
||||||
|
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
include(RegexUtils)
|
|
||||||
test_escape_string_as_regex()
|
|
||||||
|
|
||||||
file(GLOB Eigen_directory_files "*")
|
|
||||||
|
|
||||||
escape_string_as_regex(ESCAPED_CMAKE_CURRENT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
|
||||||
|
|
||||||
foreach(f ${Eigen_directory_files})
|
|
||||||
if(NOT f MATCHES "\\.txt" AND NOT f MATCHES "${ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/[.].+" AND NOT f MATCHES "${ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/src")
|
|
||||||
list(APPEND Eigen_directory_files_to_install ${f})
|
|
||||||
endif()
|
|
||||||
endforeach(f ${Eigen_directory_files})
|
|
||||||
|
|
||||||
install(FILES
|
|
||||||
${Eigen_directory_files_to_install}
|
|
||||||
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen COMPONENT Devel
|
|
||||||
)
|
|
||||||
|
|
||||||
install(DIRECTORY src DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen COMPONENT Devel FILES_MATCHING PATTERN "*.h")
|
|
||||||
|
|
@ -43,4 +43,3 @@
|
||||||
#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: */
|
|
||||||
|
|
|
||||||
|
|
@ -11,251 +11,55 @@
|
||||||
#ifndef EIGEN_CORE_H
|
#ifndef EIGEN_CORE_H
|
||||||
#define EIGEN_CORE_H
|
#define EIGEN_CORE_H
|
||||||
|
|
||||||
// first thing Eigen does: stop the compiler from committing suicide
|
// first thing Eigen does: stop the compiler from reporting useless warnings.
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
#if defined(__CUDACC__) && !defined(EIGEN_NO_CUDA)
|
// then include this file where all our macros are defined. It's really important to do it first because
|
||||||
#define EIGEN_CUDACC __CUDACC__
|
// it's where we do all the compiler/OS/arch detections and define most defaults.
|
||||||
#endif
|
#include "src/Core/util/Macros.h"
|
||||||
|
|
||||||
#if defined(__CUDA_ARCH__) && !defined(EIGEN_NO_CUDA)
|
// This detects SSE/AVX/NEON/etc. and configure alignment settings
|
||||||
#define EIGEN_CUDA_ARCH __CUDA_ARCH__
|
#include "src/Core/util/ConfigureVectorization.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__CUDACC_VER_MAJOR__) && (__CUDACC_VER_MAJOR__ >= 9)
|
// We need cuda_runtime.h/hip_runtime.h to ensure that
|
||||||
#define EIGEN_CUDACC_VER ((__CUDACC_VER_MAJOR__ * 10000) + (__CUDACC_VER_MINOR__ * 100))
|
// the EIGEN_USING_STD macro works properly on the device side
|
||||||
#elif defined(__CUDACC_VER__)
|
#if defined(EIGEN_CUDACC)
|
||||||
#define EIGEN_CUDACC_VER __CUDACC_VER__
|
|
||||||
#else
|
|
||||||
#define EIGEN_CUDACC_VER 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Handle NVCC/CUDA/SYCL
|
|
||||||
#if defined(__CUDACC__) || defined(__SYCL_DEVICE_ONLY__)
|
|
||||||
// Do not try asserts on CUDA and SYCL!
|
|
||||||
#ifndef EIGEN_NO_DEBUG
|
|
||||||
#define EIGEN_NO_DEBUG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EIGEN_INTERNAL_DEBUGGING
|
|
||||||
#undef EIGEN_INTERNAL_DEBUGGING
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EIGEN_EXCEPTIONS
|
|
||||||
#undef EIGEN_EXCEPTIONS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// All functions callable from CUDA code must be qualified with __device__
|
|
||||||
#ifdef __CUDACC__
|
|
||||||
// Do not try to vectorize on CUDA and SYCL!
|
|
||||||
#ifndef EIGEN_DONT_VECTORIZE
|
|
||||||
#define EIGEN_DONT_VECTORIZE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define EIGEN_DEVICE_FUNC __host__ __device__
|
|
||||||
// We need cuda_runtime.h to ensure that that EIGEN_USING_STD_MATH macro
|
|
||||||
// works properly on the device side
|
|
||||||
#include <cuda_runtime.h>
|
#include <cuda_runtime.h>
|
||||||
#else
|
#elif defined(EIGEN_HIPCC)
|
||||||
#define EIGEN_DEVICE_FUNC
|
#include <hip/hip_runtime.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
|
||||||
#define EIGEN_DEVICE_FUNC
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// When compiling CUDA device code with NVCC, pull in math functions from the
|
|
||||||
// global namespace. In host mode, and when device doee with clang, use the
|
|
||||||
// std versions.
|
|
||||||
#if defined(__CUDA_ARCH__) && defined(__NVCC__)
|
|
||||||
#define EIGEN_USING_STD_MATH(FUNC) using ::FUNC;
|
|
||||||
#else
|
|
||||||
#define EIGEN_USING_STD_MATH(FUNC) using std::FUNC;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (defined(_CPPUNWIND) || defined(__EXCEPTIONS)) && !defined(__CUDA_ARCH__) && !defined(EIGEN_EXCEPTIONS) && !defined(EIGEN_USE_SYCL)
|
|
||||||
#define EIGEN_EXCEPTIONS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EIGEN_EXCEPTIONS
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
#include <new>
|
#include <new>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// then include this file where all our macros are defined. It's really important to do it first because
|
|
||||||
// it's where we do all the alignment settings (platform detection and honoring the user's will if he
|
|
||||||
// defined e.g. EIGEN_DONT_ALIGN) so it needs to be done before we do anything with vectorization.
|
|
||||||
#include "src/Core/util/Macros.h"
|
|
||||||
|
|
||||||
// Disable the ipa-cp-clone optimization flag with MinGW 6.x or newer (enabled by default with -O3)
|
// Disable the ipa-cp-clone optimization flag with MinGW 6.x or newer (enabled by default with -O3)
|
||||||
// See http://eigen.tuxfamily.org/bz/show_bug.cgi?id=556 for details.
|
// See http://eigen.tuxfamily.org/bz/show_bug.cgi?id=556 for details.
|
||||||
#if EIGEN_COMP_MINGW && EIGEN_GNUC_AT_LEAST(4,6)
|
#if EIGEN_COMP_MINGW && EIGEN_GNUC_AT_LEAST(4,6) && EIGEN_GNUC_AT_MOST(5,5)
|
||||||
#pragma GCC optimize ("-fno-ipa-cp-clone")
|
#pragma GCC optimize ("-fno-ipa-cp-clone")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Prevent ICC from specializing std::complex operators that silently fail
|
||||||
|
// on device. This allows us to use our own device-compatible specializations
|
||||||
|
// instead.
|
||||||
|
#if defined(EIGEN_COMP_ICC) && defined(EIGEN_GPU_COMPILE_PHASE) \
|
||||||
|
&& !defined(_OVERRIDE_COMPLEX_SPECIALIZATION_)
|
||||||
|
#define _OVERRIDE_COMPLEX_SPECIALIZATION_ 1
|
||||||
|
#endif
|
||||||
#include <complex>
|
#include <complex>
|
||||||
|
|
||||||
// this include file manages BLAS and MKL related macros
|
// this include file manages BLAS and MKL related macros
|
||||||
// and inclusion of their respective header files
|
// and inclusion of their respective header files
|
||||||
#include "src/Core/util/MKL_support.h"
|
#include "src/Core/util/MKL_support.h"
|
||||||
|
|
||||||
// if alignment is disabled, then disable vectorization. Note: EIGEN_MAX_ALIGN_BYTES is the proper check, it takes into
|
|
||||||
// account both the user's will (EIGEN_MAX_ALIGN_BYTES,EIGEN_DONT_ALIGN) and our own platform checks
|
#if defined(EIGEN_HAS_CUDA_FP16) || defined(EIGEN_HAS_HIP_FP16)
|
||||||
#if EIGEN_MAX_ALIGN_BYTES==0
|
#define EIGEN_HAS_GPU_FP16
|
||||||
#ifndef EIGEN_DONT_VECTORIZE
|
|
||||||
#define EIGEN_DONT_VECTORIZE
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if EIGEN_COMP_MSVC
|
#if defined(EIGEN_HAS_CUDA_BF16) || defined(EIGEN_HAS_HIP_BF16)
|
||||||
#include <malloc.h> // for _aligned_malloc -- need it regardless of whether vectorization is enabled
|
#define EIGEN_HAS_GPU_BF16
|
||||||
#if (EIGEN_COMP_MSVC >= 1500) // 2008 or later
|
|
||||||
// Remember that usage of defined() in a #define is undefined by the standard.
|
|
||||||
// a user reported that in 64-bit mode, MSVC doesn't care to define _M_IX86_FP.
|
|
||||||
#if (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || EIGEN_ARCH_x86_64
|
|
||||||
#define EIGEN_SSE2_ON_MSVC_2008_OR_LATER
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
// Remember that usage of defined() in a #define is undefined by the standard
|
|
||||||
#if (defined __SSE2__) && ( (!EIGEN_COMP_GNUC) || EIGEN_COMP_ICC || EIGEN_GNUC_AT_LEAST(4,2) )
|
|
||||||
#define EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef EIGEN_DONT_VECTORIZE
|
|
||||||
|
|
||||||
#if defined (EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER)
|
|
||||||
|
|
||||||
// Defines symbols for compile-time detection of which instructions are
|
|
||||||
// used.
|
|
||||||
// EIGEN_VECTORIZE_YY is defined if and only if the instruction set YY is used
|
|
||||||
#define EIGEN_VECTORIZE
|
|
||||||
#define EIGEN_VECTORIZE_SSE
|
|
||||||
#define EIGEN_VECTORIZE_SSE2
|
|
||||||
|
|
||||||
// Detect sse3/ssse3/sse4:
|
|
||||||
// gcc and icc defines __SSE3__, ...
|
|
||||||
// there is no way to know about this on msvc. You can define EIGEN_VECTORIZE_SSE* if you
|
|
||||||
// want to force the use of those instructions with msvc.
|
|
||||||
#ifdef __SSE3__
|
|
||||||
#define EIGEN_VECTORIZE_SSE3
|
|
||||||
#endif
|
|
||||||
#ifdef __SSSE3__
|
|
||||||
#define EIGEN_VECTORIZE_SSSE3
|
|
||||||
#endif
|
|
||||||
#ifdef __SSE4_1__
|
|
||||||
#define EIGEN_VECTORIZE_SSE4_1
|
|
||||||
#endif
|
|
||||||
#ifdef __SSE4_2__
|
|
||||||
#define EIGEN_VECTORIZE_SSE4_2
|
|
||||||
#endif
|
|
||||||
#ifdef __AVX__
|
|
||||||
#define EIGEN_VECTORIZE_AVX
|
|
||||||
#define EIGEN_VECTORIZE_SSE3
|
|
||||||
#define EIGEN_VECTORIZE_SSSE3
|
|
||||||
#define EIGEN_VECTORIZE_SSE4_1
|
|
||||||
#define EIGEN_VECTORIZE_SSE4_2
|
|
||||||
#endif
|
|
||||||
#ifdef __AVX2__
|
|
||||||
#define EIGEN_VECTORIZE_AVX2
|
|
||||||
#endif
|
|
||||||
#ifdef __FMA__
|
|
||||||
#define EIGEN_VECTORIZE_FMA
|
|
||||||
#endif
|
|
||||||
#if defined(__AVX512F__) && defined(EIGEN_ENABLE_AVX512)
|
|
||||||
#define EIGEN_VECTORIZE_AVX512
|
|
||||||
#define EIGEN_VECTORIZE_AVX2
|
|
||||||
#define EIGEN_VECTORIZE_AVX
|
|
||||||
#define EIGEN_VECTORIZE_FMA
|
|
||||||
#ifdef __AVX512DQ__
|
|
||||||
#define EIGEN_VECTORIZE_AVX512DQ
|
|
||||||
#endif
|
|
||||||
#ifdef __AVX512ER__
|
|
||||||
#define EIGEN_VECTORIZE_AVX512ER
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// include files
|
|
||||||
|
|
||||||
// This extern "C" works around a MINGW-w64 compilation issue
|
|
||||||
// https://sourceforge.net/tracker/index.php?func=detail&aid=3018394&group_id=202880&atid=983354
|
|
||||||
// In essence, intrin.h is included by windows.h and also declares intrinsics (just as emmintrin.h etc. below do).
|
|
||||||
// However, intrin.h uses an extern "C" declaration, and g++ thus complains of duplicate declarations
|
|
||||||
// with conflicting linkage. The linkage for intrinsics doesn't matter, but at that stage the compiler doesn't know;
|
|
||||||
// so, to avoid compile errors when windows.h is included after Eigen/Core, ensure intrinsics are extern "C" here too.
|
|
||||||
// notice that since these are C headers, the extern "C" is theoretically needed anyways.
|
|
||||||
extern "C" {
|
|
||||||
// In theory we should only include immintrin.h and not the other *mmintrin.h header files directly.
|
|
||||||
// Doing so triggers some issues with ICC. However old gcc versions seems to not have this file, thus:
|
|
||||||
#if EIGEN_COMP_ICC >= 1110
|
|
||||||
#include <immintrin.h>
|
|
||||||
#else
|
|
||||||
#include <mmintrin.h>
|
|
||||||
#include <emmintrin.h>
|
|
||||||
#include <xmmintrin.h>
|
|
||||||
#ifdef EIGEN_VECTORIZE_SSE3
|
|
||||||
#include <pmmintrin.h>
|
|
||||||
#endif
|
|
||||||
#ifdef EIGEN_VECTORIZE_SSSE3
|
|
||||||
#include <tmmintrin.h>
|
|
||||||
#endif
|
|
||||||
#ifdef EIGEN_VECTORIZE_SSE4_1
|
|
||||||
#include <smmintrin.h>
|
|
||||||
#endif
|
|
||||||
#ifdef EIGEN_VECTORIZE_SSE4_2
|
|
||||||
#include <nmmintrin.h>
|
|
||||||
#endif
|
|
||||||
#if defined(EIGEN_VECTORIZE_AVX) || defined(EIGEN_VECTORIZE_AVX512)
|
|
||||||
#include <immintrin.h>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
} // end extern "C"
|
|
||||||
#elif defined __VSX__
|
|
||||||
#define EIGEN_VECTORIZE
|
|
||||||
#define EIGEN_VECTORIZE_VSX
|
|
||||||
#include <altivec.h>
|
|
||||||
// We need to #undef all these ugly tokens defined in <altivec.h>
|
|
||||||
// => use __vector instead of vector
|
|
||||||
#undef bool
|
|
||||||
#undef vector
|
|
||||||
#undef pixel
|
|
||||||
#elif defined __ALTIVEC__
|
|
||||||
#define EIGEN_VECTORIZE
|
|
||||||
#define EIGEN_VECTORIZE_ALTIVEC
|
|
||||||
#include <altivec.h>
|
|
||||||
// We need to #undef all these ugly tokens defined in <altivec.h>
|
|
||||||
// => use __vector instead of vector
|
|
||||||
#undef bool
|
|
||||||
#undef vector
|
|
||||||
#undef pixel
|
|
||||||
#elif (defined __ARM_NEON) || (defined __ARM_NEON__)
|
|
||||||
#define EIGEN_VECTORIZE
|
|
||||||
#define EIGEN_VECTORIZE_NEON
|
|
||||||
#include <arm_neon.h>
|
|
||||||
#elif (defined __s390x__ && defined __VEC__)
|
|
||||||
#define EIGEN_VECTORIZE
|
|
||||||
#define EIGEN_VECTORIZE_ZVECTOR
|
|
||||||
#include <vecintrin.h>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__F16C__) && !defined(EIGEN_COMP_CLANG)
|
|
||||||
// We can use the optimized fp16 to float and float to fp16 conversion routines
|
|
||||||
#define EIGEN_HAS_FP16_C
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined __CUDACC__
|
|
||||||
#define EIGEN_VECTORIZE_CUDA
|
|
||||||
#include <vector_types.h>
|
|
||||||
#if EIGEN_CUDACC_VER >= 70500
|
|
||||||
#define EIGEN_HAS_CUDA_FP16
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined EIGEN_HAS_CUDA_FP16
|
|
||||||
#include <host_defines.h>
|
|
||||||
#include <cuda_fp16.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined _OPENMP) && (!defined EIGEN_DONT_PARALLELIZE)
|
#if (defined _OPENMP) && (!defined EIGEN_DONT_PARALLELIZE)
|
||||||
|
|
@ -279,7 +83,10 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <sstream>
|
||||||
|
#ifndef EIGEN_NO_IO
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
#endif
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
@ -287,6 +94,10 @@
|
||||||
// for min/max:
|
// for min/max:
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#if EIGEN_HAS_CXX11
|
||||||
|
#include <array>
|
||||||
|
#endif
|
||||||
|
|
||||||
// for std::is_nothrow_move_assignable
|
// for std::is_nothrow_move_assignable
|
||||||
#ifdef EIGEN_INCLUDE_TYPE_TRAITS
|
#ifdef EIGEN_INCLUDE_TYPE_TRAITS
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
@ -302,38 +113,25 @@
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** \brief Namespace containing all symbols from the %Eigen library. */
|
#if defined(EIGEN_USE_SYCL)
|
||||||
namespace Eigen {
|
#undef min
|
||||||
|
#undef max
|
||||||
inline static const char *SimdInstructionSetsInUse(void) {
|
#undef isnan
|
||||||
#if defined(EIGEN_VECTORIZE_AVX512)
|
#undef isinf
|
||||||
return "AVX512, FMA, AVX2, AVX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2";
|
#undef isfinite
|
||||||
#elif defined(EIGEN_VECTORIZE_AVX)
|
#include <CL/sycl.hpp>
|
||||||
return "AVX SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2";
|
#include <map>
|
||||||
#elif defined(EIGEN_VECTORIZE_SSE4_2)
|
#include <memory>
|
||||||
return "SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2";
|
#include <utility>
|
||||||
#elif defined(EIGEN_VECTORIZE_SSE4_1)
|
#include <thread>
|
||||||
return "SSE, SSE2, SSE3, SSSE3, SSE4.1";
|
#ifndef EIGEN_SYCL_LOCAL_THREAD_DIM0
|
||||||
#elif defined(EIGEN_VECTORIZE_SSSE3)
|
#define EIGEN_SYCL_LOCAL_THREAD_DIM0 16
|
||||||
return "SSE, SSE2, SSE3, SSSE3";
|
#endif
|
||||||
#elif defined(EIGEN_VECTORIZE_SSE3)
|
#ifndef EIGEN_SYCL_LOCAL_THREAD_DIM1
|
||||||
return "SSE, SSE2, SSE3";
|
#define EIGEN_SYCL_LOCAL_THREAD_DIM1 16
|
||||||
#elif defined(EIGEN_VECTORIZE_SSE2)
|
#endif
|
||||||
return "SSE, SSE2";
|
|
||||||
#elif defined(EIGEN_VECTORIZE_ALTIVEC)
|
|
||||||
return "AltiVec";
|
|
||||||
#elif defined(EIGEN_VECTORIZE_VSX)
|
|
||||||
return "VSX";
|
|
||||||
#elif defined(EIGEN_VECTORIZE_NEON)
|
|
||||||
return "ARM NEON";
|
|
||||||
#elif defined(EIGEN_VECTORIZE_ZVECTOR)
|
|
||||||
return "S390X ZVECTOR";
|
|
||||||
#else
|
|
||||||
return "None";
|
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#if defined EIGEN2_SUPPORT_STAGE40_FULL_EIGEN3_STRICTNESS || defined EIGEN2_SUPPORT_STAGE30_FULL_EIGEN3_API || defined EIGEN2_SUPPORT_STAGE20_RESOLVE_API_CONFLICTS || defined EIGEN2_SUPPORT_STAGE10_FULL_EIGEN2_API || defined EIGEN2_SUPPORT
|
#if defined EIGEN2_SUPPORT_STAGE40_FULL_EIGEN3_STRICTNESS || defined EIGEN2_SUPPORT_STAGE30_FULL_EIGEN3_API || defined EIGEN2_SUPPORT_STAGE20_RESOLVE_API_CONFLICTS || defined EIGEN2_SUPPORT_STAGE10_FULL_EIGEN2_API || defined EIGEN2_SUPPORT
|
||||||
// This will generate an error message:
|
// This will generate an error message:
|
||||||
|
|
@ -366,58 +164,90 @@ using std::ptrdiff_t;
|
||||||
#include "src/Core/util/StaticAssert.h"
|
#include "src/Core/util/StaticAssert.h"
|
||||||
#include "src/Core/util/XprHelper.h"
|
#include "src/Core/util/XprHelper.h"
|
||||||
#include "src/Core/util/Memory.h"
|
#include "src/Core/util/Memory.h"
|
||||||
|
#include "src/Core/util/IntegralConstant.h"
|
||||||
|
#include "src/Core/util/SymbolicIndex.h"
|
||||||
|
|
||||||
#include "src/Core/NumTraits.h"
|
#include "src/Core/NumTraits.h"
|
||||||
#include "src/Core/MathFunctions.h"
|
#include "src/Core/MathFunctions.h"
|
||||||
#include "src/Core/GenericPacketMath.h"
|
#include "src/Core/GenericPacketMath.h"
|
||||||
#include "src/Core/MathFunctionsImpl.h"
|
#include "src/Core/MathFunctionsImpl.h"
|
||||||
#include "src/Core/arch/Default/ConjHelper.h"
|
#include "src/Core/arch/Default/ConjHelper.h"
|
||||||
|
// Generic half float support
|
||||||
|
#include "src/Core/arch/Default/Half.h"
|
||||||
|
#include "src/Core/arch/Default/BFloat16.h"
|
||||||
|
#include "src/Core/arch/Default/TypeCasting.h"
|
||||||
|
#include "src/Core/arch/Default/GenericPacketMathFunctionsFwd.h"
|
||||||
|
|
||||||
#if defined EIGEN_VECTORIZE_AVX512
|
#if defined EIGEN_VECTORIZE_AVX512
|
||||||
#include "src/Core/arch/SSE/PacketMath.h"
|
#include "src/Core/arch/SSE/PacketMath.h"
|
||||||
|
#include "src/Core/arch/SSE/TypeCasting.h"
|
||||||
|
#include "src/Core/arch/SSE/Complex.h"
|
||||||
#include "src/Core/arch/AVX/PacketMath.h"
|
#include "src/Core/arch/AVX/PacketMath.h"
|
||||||
|
#include "src/Core/arch/AVX/TypeCasting.h"
|
||||||
|
#include "src/Core/arch/AVX/Complex.h"
|
||||||
#include "src/Core/arch/AVX512/PacketMath.h"
|
#include "src/Core/arch/AVX512/PacketMath.h"
|
||||||
|
#include "src/Core/arch/AVX512/TypeCasting.h"
|
||||||
|
#include "src/Core/arch/AVX512/Complex.h"
|
||||||
|
#include "src/Core/arch/SSE/MathFunctions.h"
|
||||||
|
#include "src/Core/arch/AVX/MathFunctions.h"
|
||||||
#include "src/Core/arch/AVX512/MathFunctions.h"
|
#include "src/Core/arch/AVX512/MathFunctions.h"
|
||||||
#elif defined EIGEN_VECTORIZE_AVX
|
#elif defined EIGEN_VECTORIZE_AVX
|
||||||
// Use AVX for floats and doubles, SSE for integers
|
// Use AVX for floats and doubles, SSE for integers
|
||||||
#include "src/Core/arch/SSE/PacketMath.h"
|
#include "src/Core/arch/SSE/PacketMath.h"
|
||||||
#include "src/Core/arch/SSE/Complex.h"
|
|
||||||
#include "src/Core/arch/SSE/MathFunctions.h"
|
|
||||||
#include "src/Core/arch/AVX/PacketMath.h"
|
|
||||||
#include "src/Core/arch/AVX/MathFunctions.h"
|
|
||||||
#include "src/Core/arch/AVX/Complex.h"
|
|
||||||
#include "src/Core/arch/AVX/TypeCasting.h"
|
|
||||||
#include "src/Core/arch/SSE/TypeCasting.h"
|
#include "src/Core/arch/SSE/TypeCasting.h"
|
||||||
|
#include "src/Core/arch/SSE/Complex.h"
|
||||||
|
#include "src/Core/arch/AVX/PacketMath.h"
|
||||||
|
#include "src/Core/arch/AVX/TypeCasting.h"
|
||||||
|
#include "src/Core/arch/AVX/Complex.h"
|
||||||
|
#include "src/Core/arch/SSE/MathFunctions.h"
|
||||||
|
#include "src/Core/arch/AVX/MathFunctions.h"
|
||||||
#elif defined EIGEN_VECTORIZE_SSE
|
#elif defined EIGEN_VECTORIZE_SSE
|
||||||
#include "src/Core/arch/SSE/PacketMath.h"
|
#include "src/Core/arch/SSE/PacketMath.h"
|
||||||
|
#include "src/Core/arch/SSE/TypeCasting.h"
|
||||||
#include "src/Core/arch/SSE/MathFunctions.h"
|
#include "src/Core/arch/SSE/MathFunctions.h"
|
||||||
#include "src/Core/arch/SSE/Complex.h"
|
#include "src/Core/arch/SSE/Complex.h"
|
||||||
#include "src/Core/arch/SSE/TypeCasting.h"
|
|
||||||
#elif defined(EIGEN_VECTORIZE_ALTIVEC) || defined(EIGEN_VECTORIZE_VSX)
|
#elif defined(EIGEN_VECTORIZE_ALTIVEC) || defined(EIGEN_VECTORIZE_VSX)
|
||||||
#include "src/Core/arch/AltiVec/PacketMath.h"
|
#include "src/Core/arch/AltiVec/PacketMath.h"
|
||||||
#include "src/Core/arch/AltiVec/MathFunctions.h"
|
#include "src/Core/arch/AltiVec/MathFunctions.h"
|
||||||
#include "src/Core/arch/AltiVec/Complex.h"
|
#include "src/Core/arch/AltiVec/Complex.h"
|
||||||
#elif defined EIGEN_VECTORIZE_NEON
|
#elif defined EIGEN_VECTORIZE_NEON
|
||||||
#include "src/Core/arch/NEON/PacketMath.h"
|
#include "src/Core/arch/NEON/PacketMath.h"
|
||||||
|
#include "src/Core/arch/NEON/TypeCasting.h"
|
||||||
#include "src/Core/arch/NEON/MathFunctions.h"
|
#include "src/Core/arch/NEON/MathFunctions.h"
|
||||||
#include "src/Core/arch/NEON/Complex.h"
|
#include "src/Core/arch/NEON/Complex.h"
|
||||||
|
#elif defined EIGEN_VECTORIZE_SVE
|
||||||
|
#include "src/Core/arch/SVE/PacketMath.h"
|
||||||
|
#include "src/Core/arch/SVE/TypeCasting.h"
|
||||||
|
#include "src/Core/arch/SVE/MathFunctions.h"
|
||||||
#elif defined EIGEN_VECTORIZE_ZVECTOR
|
#elif defined EIGEN_VECTORIZE_ZVECTOR
|
||||||
#include "src/Core/arch/ZVector/PacketMath.h"
|
#include "src/Core/arch/ZVector/PacketMath.h"
|
||||||
#include "src/Core/arch/ZVector/MathFunctions.h"
|
#include "src/Core/arch/ZVector/MathFunctions.h"
|
||||||
#include "src/Core/arch/ZVector/Complex.h"
|
#include "src/Core/arch/ZVector/Complex.h"
|
||||||
|
#elif defined EIGEN_VECTORIZE_MSA
|
||||||
|
#include "src/Core/arch/MSA/PacketMath.h"
|
||||||
|
#include "src/Core/arch/MSA/MathFunctions.h"
|
||||||
|
#include "src/Core/arch/MSA/Complex.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Half float support
|
#if defined EIGEN_VECTORIZE_GPU
|
||||||
#include "src/Core/arch/CUDA/Half.h"
|
#include "src/Core/arch/GPU/PacketMath.h"
|
||||||
#include "src/Core/arch/CUDA/PacketMathHalf.h"
|
#include "src/Core/arch/GPU/MathFunctions.h"
|
||||||
#include "src/Core/arch/CUDA/TypeCasting.h"
|
#include "src/Core/arch/GPU/TypeCasting.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined EIGEN_VECTORIZE_CUDA
|
#if defined(EIGEN_USE_SYCL)
|
||||||
#include "src/Core/arch/CUDA/PacketMath.h"
|
#include "src/Core/arch/SYCL/SyclMemoryModel.h"
|
||||||
#include "src/Core/arch/CUDA/MathFunctions.h"
|
#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
|
||||||
|
|
||||||
#include "src/Core/arch/Default/Settings.h"
|
#include "src/Core/arch/Default/Settings.h"
|
||||||
|
// This file provides generic implementations valid for scalar as well
|
||||||
|
#include "src/Core/arch/Default/GenericPacketMathFunctions.h"
|
||||||
|
|
||||||
#include "src/Core/functors/TernaryFunctors.h"
|
#include "src/Core/functors/TernaryFunctors.h"
|
||||||
#include "src/Core/functors/BinaryFunctors.h"
|
#include "src/Core/functors/BinaryFunctors.h"
|
||||||
|
|
@ -428,9 +258,16 @@ using std::ptrdiff_t;
|
||||||
|
|
||||||
// Specialized functors to enable the processing of complex numbers
|
// Specialized functors to enable the processing of complex numbers
|
||||||
// on CUDA devices
|
// on CUDA devices
|
||||||
|
#ifdef EIGEN_CUDACC
|
||||||
#include "src/Core/arch/CUDA/Complex.h"
|
#include "src/Core/arch/CUDA/Complex.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "src/Core/util/IndexedViewHelper.h"
|
||||||
|
#include "src/Core/util/ReshapedHelper.h"
|
||||||
|
#include "src/Core/ArithmeticSequence.h"
|
||||||
|
#ifndef EIGEN_NO_IO
|
||||||
#include "src/Core/IO.h"
|
#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"
|
||||||
|
|
@ -471,6 +308,8 @@ using std::ptrdiff_t;
|
||||||
#include "src/Core/Ref.h"
|
#include "src/Core/Ref.h"
|
||||||
#include "src/Core/Block.h"
|
#include "src/Core/Block.h"
|
||||||
#include "src/Core/VectorBlock.h"
|
#include "src/Core/VectorBlock.h"
|
||||||
|
#include "src/Core/IndexedView.h"
|
||||||
|
#include "src/Core/Reshaped.h"
|
||||||
#include "src/Core/Transpose.h"
|
#include "src/Core/Transpose.h"
|
||||||
#include "src/Core/DiagonalMatrix.h"
|
#include "src/Core/DiagonalMatrix.h"
|
||||||
#include "src/Core/Diagonal.h"
|
#include "src/Core/Diagonal.h"
|
||||||
|
|
@ -507,13 +346,21 @@ using std::ptrdiff_t;
|
||||||
#include "src/Core/CoreIterators.h"
|
#include "src/Core/CoreIterators.h"
|
||||||
#include "src/Core/ConditionEstimator.h"
|
#include "src/Core/ConditionEstimator.h"
|
||||||
|
|
||||||
|
#if defined(EIGEN_VECTORIZE_ALTIVEC) || defined(EIGEN_VECTORIZE_VSX)
|
||||||
|
#include "src/Core/arch/AltiVec/MatrixProduct.h"
|
||||||
|
#elif defined EIGEN_VECTORIZE_NEON
|
||||||
|
#include "src/Core/arch/NEON/GeneralBlockPanelKernel.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "src/Core/BooleanRedux.h"
|
#include "src/Core/BooleanRedux.h"
|
||||||
#include "src/Core/Select.h"
|
#include "src/Core/Select.h"
|
||||||
#include "src/Core/VectorwiseOp.h"
|
#include "src/Core/VectorwiseOp.h"
|
||||||
|
#include "src/Core/PartialReduxEvaluator.h"
|
||||||
#include "src/Core/Random.h"
|
#include "src/Core/Random.h"
|
||||||
#include "src/Core/Replicate.h"
|
#include "src/Core/Replicate.h"
|
||||||
#include "src/Core/Reverse.h"
|
#include "src/Core/Reverse.h"
|
||||||
#include "src/Core/ArrayWrapper.h"
|
#include "src/Core/ArrayWrapper.h"
|
||||||
|
#include "src/Core/StlIterators.h"
|
||||||
|
|
||||||
#ifdef EIGEN_USE_BLAS
|
#ifdef EIGEN_USE_BLAS
|
||||||
#include "src/Core/products/GeneralMatrixMatrix_BLAS.h"
|
#include "src/Core/products/GeneralMatrixMatrix_BLAS.h"
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,14 @@
|
||||||
|
|
||||||
#include "Core"
|
#include "Core"
|
||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
|
||||||
|
|
||||||
#include "Cholesky"
|
#include "Cholesky"
|
||||||
#include "Jacobi"
|
#include "Jacobi"
|
||||||
#include "Householder"
|
#include "Householder"
|
||||||
#include "LU"
|
#include "LU"
|
||||||
#include "Geometry"
|
#include "Geometry"
|
||||||
|
|
||||||
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
/** \defgroup Eigenvalues_Module Eigenvalues module
|
/** \defgroup Eigenvalues_Module Eigenvalues module
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
|
@ -58,4 +58,3 @@
|
||||||
#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: */
|
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,12 @@
|
||||||
|
|
||||||
#include "Core"
|
#include "Core"
|
||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
|
||||||
|
|
||||||
#include "SVD"
|
#include "SVD"
|
||||||
#include "LU"
|
#include "LU"
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
/** \defgroup Geometry_Module Geometry module
|
/** \defgroup Geometry_Module Geometry module
|
||||||
*
|
*
|
||||||
* This module provides support for:
|
* This module provides support for:
|
||||||
|
|
@ -49,14 +49,11 @@
|
||||||
#include "src/Geometry/AlignedBox.h"
|
#include "src/Geometry/AlignedBox.h"
|
||||||
#include "src/Geometry/Umeyama.h"
|
#include "src/Geometry/Umeyama.h"
|
||||||
|
|
||||||
// Use the SSE optimized version whenever possible. At the moment the
|
// Use the SSE optimized version whenever possible.
|
||||||
// SSE version doesn't compile when AVX is enabled
|
#if (defined EIGEN_VECTORIZE_SSE) || (defined EIGEN_VECTORIZE_NEON)
|
||||||
#if defined EIGEN_VECTORIZE_SSE && !defined EIGEN_VECTORIZE_AVX
|
#include "src/Geometry/arch/Geometry_SIMD.h"
|
||||||
#include "src/Geometry/arch/Geometry_SSE.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_GEOMETRY_MODULE_H
|
#endif // EIGEN_GEOMETRY_MODULE_H
|
||||||
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,4 +27,3 @@
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_HOUSEHOLDER_MODULE_H
|
#endif // EIGEN_HOUSEHOLDER_MODULE_H
|
||||||
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
|
||||||
|
|
|
||||||
|
|
@ -29,5 +29,4 @@
|
||||||
#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: */
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +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_KLUSUPPORT_MODULE_H
|
||||||
|
#define EIGEN_KLUSUPPORT_MODULE_H
|
||||||
|
|
||||||
|
#include <Eigen/SparseCore>
|
||||||
|
|
||||||
|
#include <Eigen/src/Core/util/DisableStupidWarnings.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <btf.h>
|
||||||
|
#include <klu.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \ingroup Support_modules
|
||||||
|
* \defgroup KLUSupport_Module KLUSupport module
|
||||||
|
*
|
||||||
|
* This module provides an interface to the KLU library which is part of the <a href="http://www.suitesparse.com">suitesparse</a> package.
|
||||||
|
* It provides the following factorization class:
|
||||||
|
* - class KLU: a sparse LU factorization, well-suited for circuit simulation.
|
||||||
|
*
|
||||||
|
* \code
|
||||||
|
* #include <Eigen/KLUSupport>
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* In order to use this module, the klu and btf headers must be accessible from the include paths, and your binary must be linked to the klu library and its dependencies.
|
||||||
|
* The dependencies depend on how umfpack has been compiled.
|
||||||
|
* For a cmake based project, you can use our FindKLU.cmake module to help you in this task.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "src/KLUSupport/KLUSupport.h"
|
||||||
|
|
||||||
|
#include <Eigen/src/Core/util/ReenableStupidWarnings.h>
|
||||||
|
|
||||||
|
#endif // EIGEN_KLUSUPPORT_MODULE_H
|
||||||
|
|
@ -38,13 +38,10 @@
|
||||||
#include "src/LU/Determinant.h"
|
#include "src/LU/Determinant.h"
|
||||||
#include "src/LU/InverseImpl.h"
|
#include "src/LU/InverseImpl.h"
|
||||||
|
|
||||||
// Use the SSE optimized version whenever possible. At the moment the
|
#if defined EIGEN_VECTORIZE_SSE || defined EIGEN_VECTORIZE_NEON
|
||||||
// SSE version doesn't compile when AVX is enabled
|
#include "src/LU/arch/InverseSize4.h"
|
||||||
#if defined EIGEN_VECTORIZE_SSE && !defined EIGEN_VECTORIZE_AVX
|
|
||||||
#include "src/LU/arch/Inverse_SSE.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_LU_MODULE_H
|
#endif // EIGEN_LU_MODULE_H
|
||||||
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
|
||||||
|
|
|
||||||
|
|
@ -63,10 +63,7 @@
|
||||||
* \endcode
|
* \endcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EIGEN_MPL2_ONLY
|
|
||||||
#include "src/OrderingMethods/Amd.h"
|
#include "src/OrderingMethods/Amd.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "src/OrderingMethods/Ordering.h"
|
#include "src/OrderingMethods/Ordering.h"
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ extern "C" {
|
||||||
* \endcode
|
* \endcode
|
||||||
*
|
*
|
||||||
* In order to use this module, the PaSTiX headers must be accessible from the include paths, and your binary must be linked to the PaSTiX library and its dependencies.
|
* In order to use this module, the PaSTiX headers must be accessible from the include paths, and your binary must be linked to the PaSTiX library and its dependencies.
|
||||||
|
* This wrapper resuires PaStiX version 5.x compiled without MPI support.
|
||||||
* The dependencies depend on how PaSTiX has been compiled.
|
* The dependencies depend on how PaSTiX has been compiled.
|
||||||
* For a cmake based project, you can use our FindPaSTiX.cmake module to help you in this task.
|
* For a cmake based project, you can use our FindPaSTiX.cmake module to help you in this task.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,12 @@
|
||||||
|
|
||||||
#include "Core"
|
#include "Core"
|
||||||
|
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
|
||||||
|
|
||||||
#include "Cholesky"
|
#include "Cholesky"
|
||||||
#include "Jacobi"
|
#include "Jacobi"
|
||||||
#include "Householder"
|
#include "Householder"
|
||||||
|
|
||||||
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
/** \defgroup QR_Module QR module
|
/** \defgroup QR_Module QR module
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
|
@ -48,4 +48,3 @@
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_QR_MODULE_H
|
#endif // EIGEN_QR_MODULE_H
|
||||||
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
|
||||||
|
|
|
||||||
|
|
@ -37,4 +37,3 @@ void *qRealloc(void *ptr, std::size_t size)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // EIGEN_QTMALLOC_MODULE_H
|
#endif // EIGEN_QTMALLOC_MODULE_H
|
||||||
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
|
||||||
|
|
|
||||||
|
|
@ -48,4 +48,3 @@
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_SVD_MODULE_H
|
#endif // EIGEN_SVD_MODULE_H
|
||||||
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,7 @@
|
||||||
|
|
||||||
#include "SparseCore"
|
#include "SparseCore"
|
||||||
#include "OrderingMethods"
|
#include "OrderingMethods"
|
||||||
#ifndef EIGEN_MPL2_ONLY
|
|
||||||
#include "SparseCholesky"
|
#include "SparseCholesky"
|
||||||
#endif
|
|
||||||
#include "SparseLU"
|
#include "SparseLU"
|
||||||
#include "SparseQR"
|
#include "SparseQR"
|
||||||
#include "IterativeLinearSolvers"
|
#include "IterativeLinearSolvers"
|
||||||
|
|
|
||||||
|
|
@ -30,16 +30,8 @@
|
||||||
* \endcode
|
* \endcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef EIGEN_MPL2_ONLY
|
|
||||||
#error The SparseCholesky module has nothing to offer in MPL2 only mode
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "src/SparseCholesky/SimplicialCholesky.h"
|
#include "src/SparseCholesky/SimplicialCholesky.h"
|
||||||
|
|
||||||
#ifndef EIGEN_MPL2_ONLY
|
|
||||||
#include "src/SparseCholesky/SimplicialCholesky_impl.h"
|
#include "src/SparseCholesky/SimplicialCholesky_impl.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_SPARSECHOLESKY_MODULE_H
|
#endif // EIGEN_SPARSECHOLESKY_MODULE_H
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@
|
||||||
// Ordering interface
|
// Ordering interface
|
||||||
#include "OrderingMethods"
|
#include "OrderingMethods"
|
||||||
|
|
||||||
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
#include "src/SparseLU/SparseLU_gemm_kernel.h"
|
#include "src/SparseLU/SparseLU_gemm_kernel.h"
|
||||||
|
|
||||||
#include "src/SparseLU/SparseLU_Structs.h"
|
#include "src/SparseLU/SparseLU_Structs.h"
|
||||||
|
|
@ -43,4 +45,6 @@
|
||||||
#include "src/SparseLU/SparseLU_Utils.h"
|
#include "src/SparseLU/SparseLU_Utils.h"
|
||||||
#include "src/SparseLU/SparseLU.h"
|
#include "src/SparseLU/SparseLU.h"
|
||||||
|
|
||||||
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_SPARSELU_MODULE_H
|
#endif // EIGEN_SPARSELU_MODULE_H
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "OrderingMethods"
|
|
||||||
#include "src/SparseCore/SparseColEtree.h"
|
#include "src/SparseCore/SparseColEtree.h"
|
||||||
#include "src/SparseQR/SparseQR.h"
|
#include "src/SparseQR/SparseQR.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,15 @@
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
template<typename _MatrixType, int _UpLo> struct traits<LDLT<_MatrixType, _UpLo> >
|
||||||
|
: traits<_MatrixType>
|
||||||
|
{
|
||||||
|
typedef MatrixXpr XprKind;
|
||||||
|
typedef SolverStorage StorageKind;
|
||||||
|
typedef int StorageIndex;
|
||||||
|
enum { Flags = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
template<typename MatrixType, int UpLo> struct LDLT_Traits;
|
template<typename MatrixType, int UpLo> struct LDLT_Traits;
|
||||||
|
|
||||||
// PositiveSemiDef means positive semi-definite and non-zero; same for NegativeSemiDef
|
// PositiveSemiDef means positive semi-definite and non-zero; same for NegativeSemiDef
|
||||||
|
|
@ -36,7 +45,7 @@ namespace internal {
|
||||||
* matrix \f$ A \f$ such that \f$ A = P^TLDL^*P \f$, where P is a permutation matrix, L
|
* matrix \f$ A \f$ such that \f$ A = P^TLDL^*P \f$, where P is a permutation matrix, L
|
||||||
* is lower triangular with a unit diagonal and D is a diagonal matrix.
|
* is lower triangular with a unit diagonal and D is a diagonal matrix.
|
||||||
*
|
*
|
||||||
* The decomposition uses pivoting to ensure stability, so that L will have
|
* The decomposition uses pivoting to ensure stability, so that D 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.
|
||||||
*
|
*
|
||||||
|
|
@ -48,20 +57,19 @@ namespace internal {
|
||||||
* \sa MatrixBase::ldlt(), SelfAdjointView::ldlt(), class LLT
|
* \sa MatrixBase::ldlt(), SelfAdjointView::ldlt(), class LLT
|
||||||
*/
|
*/
|
||||||
template<typename _MatrixType, int _UpLo> class LDLT
|
template<typename _MatrixType, int _UpLo> class LDLT
|
||||||
|
: public SolverBase<LDLT<_MatrixType, _UpLo> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef _MatrixType MatrixType;
|
typedef _MatrixType MatrixType;
|
||||||
|
typedef SolverBase<LDLT> Base;
|
||||||
|
friend class SolverBase<LDLT>;
|
||||||
|
|
||||||
|
EIGEN_GENERIC_PUBLIC_INTERFACE(LDLT)
|
||||||
enum {
|
enum {
|
||||||
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
|
|
||||||
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
|
|
||||||
MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
|
MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
|
||||||
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
|
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
|
||||||
UpLo = _UpLo
|
UpLo = _UpLo
|
||||||
};
|
};
|
||||||
typedef typename MatrixType::Scalar Scalar;
|
|
||||||
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
|
|
||||||
typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
|
|
||||||
typedef typename MatrixType::StorageIndex StorageIndex;
|
|
||||||
typedef Matrix<Scalar, RowsAtCompileTime, 1, 0, MaxRowsAtCompileTime, 1> TmpMatrixType;
|
typedef Matrix<Scalar, RowsAtCompileTime, 1, 0, MaxRowsAtCompileTime, 1> TmpMatrixType;
|
||||||
|
|
||||||
typedef Transpositions<RowsAtCompileTime, MaxRowsAtCompileTime> TranspositionType;
|
typedef Transpositions<RowsAtCompileTime, MaxRowsAtCompileTime> TranspositionType;
|
||||||
|
|
@ -180,6 +188,7 @@ template<typename _MatrixType, int _UpLo> class LDLT
|
||||||
return m_sign == internal::NegativeSemiDef || m_sign == internal::ZeroSign;
|
return m_sign == internal::NegativeSemiDef || m_sign == internal::ZeroSign;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
||||||
/** \returns a solution x of \f$ A x = b \f$ using the current decomposition of A.
|
/** \returns a solution x of \f$ A x = b \f$ using the current decomposition of A.
|
||||||
*
|
*
|
||||||
* This function also supports in-place solves using the syntax <tt>x = decompositionObject.solve(x)</tt> .
|
* This function also supports in-place solves using the syntax <tt>x = decompositionObject.solve(x)</tt> .
|
||||||
|
|
@ -191,19 +200,14 @@ template<typename _MatrixType, int _UpLo> class LDLT
|
||||||
* \f$ L^* y_4 = y_3 \f$ and \f$ P x = y_4 \f$ in succession. If the matrix \f$ A \f$ is singular, then
|
* \f$ L^* y_4 = y_3 \f$ and \f$ P x = y_4 \f$ in succession. If the matrix \f$ A \f$ is singular, then
|
||||||
* \f$ D \f$ will also be singular (all the other matrices are invertible). In that case, the
|
* \f$ D \f$ will also be singular (all the other matrices are invertible). In that case, the
|
||||||
* least-square solution of \f$ D y_3 = y_2 \f$ is computed. This does not mean that this function
|
* least-square solution of \f$ D y_3 = y_2 \f$ is computed. This does not mean that this function
|
||||||
* computes the least-square solution of \f$ A x = b \f$ is \f$ A \f$ is singular.
|
* computes the least-square solution of \f$ A x = b \f$ if \f$ A \f$ is singular.
|
||||||
*
|
*
|
||||||
* \sa MatrixBase::ldlt(), SelfAdjointView::ldlt()
|
* \sa MatrixBase::ldlt(), SelfAdjointView::ldlt()
|
||||||
*/
|
*/
|
||||||
template<typename Rhs>
|
template<typename Rhs>
|
||||||
inline const Solve<LDLT, Rhs>
|
inline const Solve<LDLT, Rhs>
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
solve(const MatrixBase<Rhs>& b) const;
|
||||||
{
|
#endif
|
||||||
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
|
||||||
eigen_assert(m_matrix.rows()==b.rows()
|
|
||||||
&& "LDLT::solve(): invalid number of rows of the right hand side matrix b");
|
|
||||||
return Solve<LDLT, Rhs>(*this, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
bool solveInPlace(MatrixBase<Derived> &bAndX) const;
|
bool solveInPlace(MatrixBase<Derived> &bAndX) const;
|
||||||
|
|
@ -242,12 +246,12 @@ template<typename _MatrixType, int _UpLo> class LDLT
|
||||||
*/
|
*/
|
||||||
const LDLT& adjoint() const { return *this; };
|
const LDLT& adjoint() const { return *this; };
|
||||||
|
|
||||||
inline Index rows() const { return m_matrix.rows(); }
|
EIGEN_DEVICE_FUNC inline EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
|
||||||
inline Index cols() const { return m_matrix.cols(); }
|
EIGEN_DEVICE_FUNC inline EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
|
||||||
|
|
||||||
/** \brief Reports whether previous computation was successful.
|
/** \brief Reports whether previous computation was successful.
|
||||||
*
|
*
|
||||||
* \returns \c Success if computation was succesful,
|
* \returns \c Success if computation was successful,
|
||||||
* \c NumericalIssue if the factorization failed because of a zero pivot.
|
* \c NumericalIssue if the factorization failed because of a zero pivot.
|
||||||
*/
|
*/
|
||||||
ComputationInfo info() const
|
ComputationInfo info() const
|
||||||
|
|
@ -258,8 +262,10 @@ template<typename _MatrixType, int _UpLo> class LDLT
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
template<typename RhsType, typename DstType>
|
template<typename RhsType, typename DstType>
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
void _solve_impl(const RhsType &rhs, DstType &dst) const;
|
void _solve_impl(const RhsType &rhs, DstType &dst) const;
|
||||||
|
|
||||||
|
template<bool Conjugate, typename RhsType, typename DstType>
|
||||||
|
void _solve_impl_transposed(const RhsType &rhs, DstType &dst) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -560,14 +566,22 @@ template<typename _MatrixType, int _UpLo>
|
||||||
template<typename RhsType, typename DstType>
|
template<typename RhsType, typename DstType>
|
||||||
void LDLT<_MatrixType,_UpLo>::_solve_impl(const RhsType &rhs, DstType &dst) const
|
void LDLT<_MatrixType,_UpLo>::_solve_impl(const RhsType &rhs, DstType &dst) const
|
||||||
{
|
{
|
||||||
eigen_assert(rhs.rows() == rows());
|
_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 = m_transpositions * rhs;
|
||||||
|
|
||||||
// dst = L^-1 (P b)
|
// dst = L^-1 (P b)
|
||||||
matrixL().solveInPlace(dst);
|
// dst = L^-*T (P b)
|
||||||
|
matrixL().template conjugateIf<!Conjugate>().solveInPlace(dst);
|
||||||
|
|
||||||
// dst = D^-1 (L^-1 P b)
|
// dst = D^-* (L^-1 P b)
|
||||||
|
// dst = D^-1 (L^-*T P b)
|
||||||
// more precisely, use pseudo-inverse of D (see bug 241)
|
// more precisely, use pseudo-inverse of D (see bug 241)
|
||||||
using std::abs;
|
using std::abs;
|
||||||
const typename Diagonal<const MatrixType>::RealReturnType vecD(vectorD());
|
const typename Diagonal<const MatrixType>::RealReturnType vecD(vectorD());
|
||||||
|
|
@ -579,7 +593,6 @@ void LDLT<_MatrixType,_UpLo>::_solve_impl(const RhsType &rhs, DstType &dst) cons
|
||||||
// Moreover, Lapack's xSYTRS routines use 0 for the tolerance.
|
// Moreover, Lapack's xSYTRS routines use 0 for the tolerance.
|
||||||
// Using numeric_limits::min() gives us more robustness to denormals.
|
// Using numeric_limits::min() gives us more robustness to denormals.
|
||||||
RealScalar tolerance = (std::numeric_limits<RealScalar>::min)();
|
RealScalar tolerance = (std::numeric_limits<RealScalar>::min)();
|
||||||
|
|
||||||
for (Index i = 0; i < vecD.size(); ++i)
|
for (Index i = 0; i < vecD.size(); ++i)
|
||||||
{
|
{
|
||||||
if(abs(vecD(i)) > tolerance)
|
if(abs(vecD(i)) > tolerance)
|
||||||
|
|
@ -588,10 +601,12 @@ void LDLT<_MatrixType,_UpLo>::_solve_impl(const RhsType &rhs, DstType &dst) cons
|
||||||
dst.row(i).setZero();
|
dst.row(i).setZero();
|
||||||
}
|
}
|
||||||
|
|
||||||
// dst = L^-T (D^-1 L^-1 P b)
|
// dst = L^-* (D^-* L^-1 P b)
|
||||||
matrixU().solveInPlace(dst);
|
// dst = L^-T (D^-1 L^-*T P b)
|
||||||
|
matrixL().transpose().template conjugateIf<Conjugate>().solveInPlace(dst);
|
||||||
|
|
||||||
// dst = P^-1 (L^-T D^-1 L^-1 P b) = A^-1 b
|
// dst = P^T (L^-* D^-* L^-1 P b) = A^-1 b
|
||||||
|
// dst = P^-T (L^-T D^-1 L^-*T P b) = A^-1 b
|
||||||
dst = m_transpositions.transpose() * dst;
|
dst = m_transpositions.transpose() * dst;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,16 @@
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
namespace internal{
|
namespace internal{
|
||||||
|
|
||||||
|
template<typename _MatrixType, int _UpLo> struct traits<LLT<_MatrixType, _UpLo> >
|
||||||
|
: traits<_MatrixType>
|
||||||
|
{
|
||||||
|
typedef MatrixXpr XprKind;
|
||||||
|
typedef SolverStorage StorageKind;
|
||||||
|
typedef int StorageIndex;
|
||||||
|
enum { Flags = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
template<typename MatrixType, int UpLo> struct LLT_Traits;
|
template<typename MatrixType, int UpLo> struct LLT_Traits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,18 +64,17 @@ template<typename MatrixType, int UpLo> struct LLT_Traits;
|
||||||
* \sa MatrixBase::llt(), SelfAdjointView::llt(), class LDLT
|
* \sa MatrixBase::llt(), SelfAdjointView::llt(), class LDLT
|
||||||
*/
|
*/
|
||||||
template<typename _MatrixType, int _UpLo> class LLT
|
template<typename _MatrixType, int _UpLo> class LLT
|
||||||
|
: public SolverBase<LLT<_MatrixType, _UpLo> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef _MatrixType MatrixType;
|
typedef _MatrixType MatrixType;
|
||||||
|
typedef SolverBase<LLT> Base;
|
||||||
|
friend class SolverBase<LLT>;
|
||||||
|
|
||||||
|
EIGEN_GENERIC_PUBLIC_INTERFACE(LLT)
|
||||||
enum {
|
enum {
|
||||||
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
|
|
||||||
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
|
|
||||||
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
|
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
|
||||||
};
|
};
|
||||||
typedef typename MatrixType::Scalar Scalar;
|
|
||||||
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
|
|
||||||
typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
|
|
||||||
typedef typename MatrixType::StorageIndex StorageIndex;
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PacketSize = internal::packet_traits<Scalar>::size,
|
PacketSize = internal::packet_traits<Scalar>::size,
|
||||||
|
|
@ -100,7 +109,7 @@ template<typename _MatrixType, int _UpLo> class LLT
|
||||||
compute(matrix.derived());
|
compute(matrix.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Constructs a LDLT factorization from a given matrix
|
/** \brief Constructs a LLT factorization from a given matrix
|
||||||
*
|
*
|
||||||
* This overloaded constructor is provided for \link InplaceDecomposition inplace decomposition \endlink when
|
* This overloaded constructor is provided for \link InplaceDecomposition inplace decomposition \endlink when
|
||||||
* \c MatrixType is a Eigen::Ref.
|
* \c MatrixType is a Eigen::Ref.
|
||||||
|
|
@ -129,6 +138,7 @@ template<typename _MatrixType, int _UpLo> class LLT
|
||||||
return Traits::getL(m_matrix);
|
return Traits::getL(m_matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
||||||
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
|
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
|
||||||
*
|
*
|
||||||
* Since this LLT class assumes anyway that the matrix A is invertible, the solution
|
* Since this LLT class assumes anyway that the matrix A is invertible, the solution
|
||||||
|
|
@ -141,13 +151,8 @@ template<typename _MatrixType, int _UpLo> class LLT
|
||||||
*/
|
*/
|
||||||
template<typename Rhs>
|
template<typename Rhs>
|
||||||
inline const Solve<LLT, Rhs>
|
inline const Solve<LLT, Rhs>
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
solve(const MatrixBase<Rhs>& b) const;
|
||||||
{
|
#endif
|
||||||
eigen_assert(m_isInitialized && "LLT is not initialized.");
|
|
||||||
eigen_assert(m_matrix.rows()==b.rows()
|
|
||||||
&& "LLT::solve(): invalid number of rows of the right hand side matrix b");
|
|
||||||
return Solve<LLT, Rhs>(*this, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
void solveInPlace(const MatrixBase<Derived> &bAndX) const;
|
void solveInPlace(const MatrixBase<Derived> &bAndX) const;
|
||||||
|
|
@ -180,7 +185,7 @@ template<typename _MatrixType, int _UpLo> class LLT
|
||||||
|
|
||||||
/** \brief Reports whether previous computation was successful.
|
/** \brief Reports whether previous computation was successful.
|
||||||
*
|
*
|
||||||
* \returns \c Success if computation was succesful,
|
* \returns \c Success if computation was successful,
|
||||||
* \c NumericalIssue if the matrix.appears not to be positive definite.
|
* \c NumericalIssue if the matrix.appears not to be positive definite.
|
||||||
*/
|
*/
|
||||||
ComputationInfo info() const
|
ComputationInfo info() const
|
||||||
|
|
@ -194,18 +199,20 @@ template<typename _MatrixType, int _UpLo> class LLT
|
||||||
* This method is provided for compatibility with other matrix decompositions, thus enabling generic code such as:
|
* This method is provided for compatibility with other matrix decompositions, thus enabling generic code such as:
|
||||||
* \code x = decomposition.adjoint().solve(b) \endcode
|
* \code x = decomposition.adjoint().solve(b) \endcode
|
||||||
*/
|
*/
|
||||||
const LLT& adjoint() const { return *this; };
|
const LLT& adjoint() const EIGEN_NOEXCEPT { return *this; };
|
||||||
|
|
||||||
inline Index rows() const { return m_matrix.rows(); }
|
inline EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
|
||||||
inline Index cols() const { return m_matrix.cols(); }
|
inline EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
|
||||||
|
|
||||||
template<typename VectorType>
|
template<typename VectorType>
|
||||||
LLT rankUpdate(const VectorType& vec, const RealScalar& sigma = 1);
|
LLT & rankUpdate(const VectorType& vec, const RealScalar& sigma = 1);
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
template<typename RhsType, typename DstType>
|
template<typename RhsType, typename DstType>
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
void _solve_impl(const RhsType &rhs, DstType &dst) const;
|
void _solve_impl(const RhsType &rhs, DstType &dst) const;
|
||||||
|
|
||||||
|
template<bool Conjugate, typename RhsType, typename DstType>
|
||||||
|
void _solve_impl_transposed(const RhsType &rhs, DstType &dst) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -459,7 +466,7 @@ LLT<MatrixType,_UpLo>& LLT<MatrixType,_UpLo>::compute(const EigenBase<InputType>
|
||||||
*/
|
*/
|
||||||
template<typename _MatrixType, int _UpLo>
|
template<typename _MatrixType, int _UpLo>
|
||||||
template<typename VectorType>
|
template<typename VectorType>
|
||||||
LLT<_MatrixType,_UpLo> LLT<_MatrixType,_UpLo>::rankUpdate(const VectorType& v, const RealScalar& sigma)
|
LLT<_MatrixType,_UpLo> & LLT<_MatrixType,_UpLo>::rankUpdate(const VectorType& v, const RealScalar& sigma)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorType);
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorType);
|
||||||
eigen_assert(v.size()==m_matrix.cols());
|
eigen_assert(v.size()==m_matrix.cols());
|
||||||
|
|
@ -476,9 +483,18 @@ LLT<_MatrixType,_UpLo> LLT<_MatrixType,_UpLo>::rankUpdate(const VectorType& v, c
|
||||||
template<typename _MatrixType,int _UpLo>
|
template<typename _MatrixType,int _UpLo>
|
||||||
template<typename RhsType, typename DstType>
|
template<typename RhsType, typename DstType>
|
||||||
void LLT<_MatrixType,_UpLo>::_solve_impl(const RhsType &rhs, DstType &dst) const
|
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;
|
dst = rhs;
|
||||||
solveInPlace(dst);
|
|
||||||
|
matrixL().template conjugateIf<!Conjugate>().solveInPlace(dst);
|
||||||
|
matrixU().template conjugateIf<!Conjugate>().solveInPlace(dst);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ template<> struct cholmod_configure_matrix<std::complex<double> > {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Other scalar types are not yet suppotred by Cholmod
|
// Other scalar types are not yet supported by Cholmod
|
||||||
// template<> struct cholmod_configure_matrix<float> {
|
// template<> struct cholmod_configure_matrix<float> {
|
||||||
// template<typename CholmodType>
|
// template<typename CholmodType>
|
||||||
// static void run(CholmodType& mat) {
|
// static void run(CholmodType& mat) {
|
||||||
|
|
@ -84,7 +84,7 @@ cholmod_sparse viewAsCholmod(Ref<SparseMatrix<_Scalar,_Options,_StorageIndex> >
|
||||||
{
|
{
|
||||||
res.itype = CHOLMOD_INT;
|
res.itype = CHOLMOD_INT;
|
||||||
}
|
}
|
||||||
else if (internal::is_same<_StorageIndex,long>::value)
|
else if (internal::is_same<_StorageIndex,SuiteSparse_long>::value)
|
||||||
{
|
{
|
||||||
res.itype = CHOLMOD_LONG;
|
res.itype = CHOLMOD_LONG;
|
||||||
}
|
}
|
||||||
|
|
@ -124,6 +124,9 @@ cholmod_sparse viewAsCholmod(const SparseSelfAdjointView<const SparseMatrix<_Sca
|
||||||
|
|
||||||
if(UpLo==Upper) res.stype = 1;
|
if(UpLo==Upper) res.stype = 1;
|
||||||
if(UpLo==Lower) res.stype = -1;
|
if(UpLo==Lower) res.stype = -1;
|
||||||
|
// swap stype for rowmajor matrices (only works for real matrices)
|
||||||
|
EIGEN_STATIC_ASSERT((_Options & RowMajorBit) == 0 || NumTraits<_Scalar>::IsComplex == 0, THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
|
||||||
|
if(_Options & RowMajorBit) res.stype *=-1;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
@ -159,6 +162,44 @@ MappedSparseMatrix<Scalar,Flags,StorageIndex> viewAsEigen(cholmod_sparse& cm)
|
||||||
static_cast<StorageIndex*>(cm.p), static_cast<StorageIndex*>(cm.i),static_cast<Scalar*>(cm.x) );
|
static_cast<StorageIndex*>(cm.p), static_cast<StorageIndex*>(cm.i),static_cast<Scalar*>(cm.x) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// template specializations for int and long that call the correct cholmod method
|
||||||
|
|
||||||
|
#define EIGEN_CHOLMOD_SPECIALIZE0(ret, name) \
|
||||||
|
template<typename _StorageIndex> inline ret cm_ ## name (cholmod_common &Common) { return cholmod_ ## name (&Common); } \
|
||||||
|
template<> inline ret cm_ ## name<SuiteSparse_long> (cholmod_common &Common) { return cholmod_l_ ## name (&Common); }
|
||||||
|
|
||||||
|
#define EIGEN_CHOLMOD_SPECIALIZE1(ret, name, t1, a1) \
|
||||||
|
template<typename _StorageIndex> inline ret cm_ ## name (t1& a1, cholmod_common &Common) { return cholmod_ ## name (&a1, &Common); } \
|
||||||
|
template<> inline ret cm_ ## name<SuiteSparse_long> (t1& a1, cholmod_common &Common) { return cholmod_l_ ## name (&a1, &Common); }
|
||||||
|
|
||||||
|
EIGEN_CHOLMOD_SPECIALIZE0(int, start)
|
||||||
|
EIGEN_CHOLMOD_SPECIALIZE0(int, finish)
|
||||||
|
|
||||||
|
EIGEN_CHOLMOD_SPECIALIZE1(int, free_factor, cholmod_factor*, L)
|
||||||
|
EIGEN_CHOLMOD_SPECIALIZE1(int, free_dense, cholmod_dense*, X)
|
||||||
|
EIGEN_CHOLMOD_SPECIALIZE1(int, free_sparse, cholmod_sparse*, A)
|
||||||
|
|
||||||
|
EIGEN_CHOLMOD_SPECIALIZE1(cholmod_factor*, analyze, cholmod_sparse, A)
|
||||||
|
|
||||||
|
template<typename _StorageIndex> inline cholmod_dense* cm_solve (int sys, cholmod_factor& L, cholmod_dense& B, cholmod_common &Common) { return cholmod_solve (sys, &L, &B, &Common); }
|
||||||
|
template<> inline cholmod_dense* cm_solve<SuiteSparse_long> (int sys, cholmod_factor& L, cholmod_dense& B, cholmod_common &Common) { return cholmod_l_solve (sys, &L, &B, &Common); }
|
||||||
|
|
||||||
|
template<typename _StorageIndex> inline cholmod_sparse* cm_spsolve (int sys, cholmod_factor& L, cholmod_sparse& B, cholmod_common &Common) { return cholmod_spsolve (sys, &L, &B, &Common); }
|
||||||
|
template<> inline cholmod_sparse* cm_spsolve<SuiteSparse_long> (int sys, cholmod_factor& L, cholmod_sparse& B, cholmod_common &Common) { return cholmod_l_spsolve (sys, &L, &B, &Common); }
|
||||||
|
|
||||||
|
template<typename _StorageIndex>
|
||||||
|
inline int cm_factorize_p (cholmod_sparse* A, double beta[2], _StorageIndex* fset, std::size_t fsize, cholmod_factor* L, cholmod_common &Common) { return cholmod_factorize_p (A, beta, fset, fsize, L, &Common); }
|
||||||
|
template<>
|
||||||
|
inline int cm_factorize_p<SuiteSparse_long> (cholmod_sparse* A, double beta[2], SuiteSparse_long* fset, std::size_t fsize, cholmod_factor* L, cholmod_common &Common) { return cholmod_l_factorize_p (A, beta, fset, fsize, L, &Common); }
|
||||||
|
|
||||||
|
#undef EIGEN_CHOLMOD_SPECIALIZE0
|
||||||
|
#undef EIGEN_CHOLMOD_SPECIALIZE1
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
|
||||||
enum CholmodMode {
|
enum CholmodMode {
|
||||||
CholmodAuto, CholmodSimplicialLLt, CholmodSupernodalLLt, CholmodLDLt
|
CholmodAuto, CholmodSimplicialLLt, CholmodSupernodalLLt, CholmodLDLt
|
||||||
};
|
};
|
||||||
|
|
@ -195,7 +236,7 @@ class CholmodBase : public SparseSolverBase<Derived>
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT((internal::is_same<double,RealScalar>::value), CHOLMOD_SUPPORTS_DOUBLE_PRECISION_ONLY);
|
EIGEN_STATIC_ASSERT((internal::is_same<double,RealScalar>::value), CHOLMOD_SUPPORTS_DOUBLE_PRECISION_ONLY);
|
||||||
m_shiftOffset[0] = m_shiftOffset[1] = 0.0;
|
m_shiftOffset[0] = m_shiftOffset[1] = 0.0;
|
||||||
cholmod_start(&m_cholmod);
|
internal::cm_start<StorageIndex>(m_cholmod);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit CholmodBase(const MatrixType& matrix)
|
explicit CholmodBase(const MatrixType& matrix)
|
||||||
|
|
@ -203,15 +244,15 @@ class CholmodBase : public SparseSolverBase<Derived>
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT((internal::is_same<double,RealScalar>::value), CHOLMOD_SUPPORTS_DOUBLE_PRECISION_ONLY);
|
EIGEN_STATIC_ASSERT((internal::is_same<double,RealScalar>::value), CHOLMOD_SUPPORTS_DOUBLE_PRECISION_ONLY);
|
||||||
m_shiftOffset[0] = m_shiftOffset[1] = 0.0;
|
m_shiftOffset[0] = m_shiftOffset[1] = 0.0;
|
||||||
cholmod_start(&m_cholmod);
|
internal::cm_start<StorageIndex>(m_cholmod);
|
||||||
compute(matrix);
|
compute(matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
~CholmodBase()
|
~CholmodBase()
|
||||||
{
|
{
|
||||||
if(m_cholmodFactor)
|
if(m_cholmodFactor)
|
||||||
cholmod_free_factor(&m_cholmodFactor, &m_cholmod);
|
internal::cm_free_factor<StorageIndex>(m_cholmodFactor, m_cholmod);
|
||||||
cholmod_finish(&m_cholmod);
|
internal::cm_finish<StorageIndex>(m_cholmod);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline StorageIndex cols() const { return internal::convert_index<StorageIndex, Index>(m_cholmodFactor->n); }
|
inline StorageIndex cols() const { return internal::convert_index<StorageIndex, Index>(m_cholmodFactor->n); }
|
||||||
|
|
@ -219,7 +260,7 @@ class CholmodBase : public SparseSolverBase<Derived>
|
||||||
|
|
||||||
/** \brief Reports whether previous computation was successful.
|
/** \brief Reports whether previous computation was successful.
|
||||||
*
|
*
|
||||||
* \returns \c Success if computation was succesful,
|
* \returns \c Success if computation was successful,
|
||||||
* \c NumericalIssue if the matrix.appears to be negative.
|
* \c NumericalIssue if the matrix.appears to be negative.
|
||||||
*/
|
*/
|
||||||
ComputationInfo info() const
|
ComputationInfo info() const
|
||||||
|
|
@ -246,11 +287,11 @@ class CholmodBase : public SparseSolverBase<Derived>
|
||||||
{
|
{
|
||||||
if(m_cholmodFactor)
|
if(m_cholmodFactor)
|
||||||
{
|
{
|
||||||
cholmod_free_factor(&m_cholmodFactor, &m_cholmod);
|
internal::cm_free_factor<StorageIndex>(m_cholmodFactor, m_cholmod);
|
||||||
m_cholmodFactor = 0;
|
m_cholmodFactor = 0;
|
||||||
}
|
}
|
||||||
cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView<UpLo>());
|
cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView<UpLo>());
|
||||||
m_cholmodFactor = cholmod_analyze(&A, &m_cholmod);
|
m_cholmodFactor = internal::cm_analyze<StorageIndex>(A, m_cholmod);
|
||||||
|
|
||||||
this->m_isInitialized = true;
|
this->m_isInitialized = true;
|
||||||
this->m_info = Success;
|
this->m_info = Success;
|
||||||
|
|
@ -268,7 +309,7 @@ class CholmodBase : public SparseSolverBase<Derived>
|
||||||
{
|
{
|
||||||
eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
|
eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
|
||||||
cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView<UpLo>());
|
cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView<UpLo>());
|
||||||
cholmod_factorize_p(&A, m_shiftOffset, 0, 0, m_cholmodFactor, &m_cholmod);
|
internal::cm_factorize_p<StorageIndex>(&A, m_shiftOffset, 0, 0, m_cholmodFactor, m_cholmod);
|
||||||
|
|
||||||
// If the factorization failed, minor is the column at which it did. On success minor == n.
|
// If the factorization failed, minor is the column at which it did. On success minor == n.
|
||||||
this->m_info = (m_cholmodFactor->minor == m_cholmodFactor->n ? Success : NumericalIssue);
|
this->m_info = (m_cholmodFactor->minor == m_cholmodFactor->n ? Success : NumericalIssue);
|
||||||
|
|
@ -289,19 +330,20 @@ class CholmodBase : public SparseSolverBase<Derived>
|
||||||
EIGEN_UNUSED_VARIABLE(size);
|
EIGEN_UNUSED_VARIABLE(size);
|
||||||
eigen_assert(size==b.rows());
|
eigen_assert(size==b.rows());
|
||||||
|
|
||||||
// Cholmod needs column-major stoarge without inner-stride, which corresponds to the default behavior of Ref.
|
// 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());
|
Ref<const Matrix<typename Rhs::Scalar,Dynamic,Dynamic,ColMajor> > b_ref(b.derived());
|
||||||
|
|
||||||
cholmod_dense b_cd = viewAsCholmod(b_ref);
|
cholmod_dense b_cd = viewAsCholmod(b_ref);
|
||||||
cholmod_dense* x_cd = cholmod_solve(CHOLMOD_A, m_cholmodFactor, &b_cd, &m_cholmod);
|
cholmod_dense* x_cd = internal::cm_solve<StorageIndex>(CHOLMOD_A, *m_cholmodFactor, b_cd, m_cholmod);
|
||||||
if(!x_cd)
|
if(!x_cd)
|
||||||
{
|
{
|
||||||
this->m_info = NumericalIssue;
|
this->m_info = NumericalIssue;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO optimize this copy by swapping when possible (be careful with alignment, etc.)
|
// TODO optimize this copy by swapping when possible (be careful with alignment, etc.)
|
||||||
|
// NOTE Actually, the copy can be avoided by calling cholmod_solve2 instead of cholmod_solve
|
||||||
dest = Matrix<Scalar,Dest::RowsAtCompileTime,Dest::ColsAtCompileTime>::Map(reinterpret_cast<Scalar*>(x_cd->x),b.rows(),b.cols());
|
dest = Matrix<Scalar,Dest::RowsAtCompileTime,Dest::ColsAtCompileTime>::Map(reinterpret_cast<Scalar*>(x_cd->x),b.rows(),b.cols());
|
||||||
cholmod_free_dense(&x_cd, &m_cholmod);
|
internal::cm_free_dense<StorageIndex>(x_cd, m_cholmod);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \internal */
|
/** \internal */
|
||||||
|
|
@ -316,15 +358,16 @@ class CholmodBase : public SparseSolverBase<Derived>
|
||||||
// note: cs stands for Cholmod Sparse
|
// note: cs stands for Cholmod Sparse
|
||||||
Ref<SparseMatrix<typename RhsDerived::Scalar,ColMajor,typename RhsDerived::StorageIndex> > b_ref(b.const_cast_derived());
|
Ref<SparseMatrix<typename RhsDerived::Scalar,ColMajor,typename RhsDerived::StorageIndex> > b_ref(b.const_cast_derived());
|
||||||
cholmod_sparse b_cs = viewAsCholmod(b_ref);
|
cholmod_sparse b_cs = viewAsCholmod(b_ref);
|
||||||
cholmod_sparse* x_cs = cholmod_spsolve(CHOLMOD_A, m_cholmodFactor, &b_cs, &m_cholmod);
|
cholmod_sparse* x_cs = internal::cm_spsolve<StorageIndex>(CHOLMOD_A, *m_cholmodFactor, b_cs, m_cholmod);
|
||||||
if(!x_cs)
|
if(!x_cs)
|
||||||
{
|
{
|
||||||
this->m_info = NumericalIssue;
|
this->m_info = NumericalIssue;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO optimize this copy by swapping when possible (be careful with alignment, etc.)
|
// TODO optimize this copy by swapping when possible (be careful with alignment, etc.)
|
||||||
|
// NOTE cholmod_spsolve in fact just calls the dense solver for blocks of 4 columns at a time (similar to Eigen's sparse solver)
|
||||||
dest.derived() = viewAsEigen<typename DestDerived::Scalar,ColMajor,typename DestDerived::StorageIndex>(*x_cs);
|
dest.derived() = viewAsEigen<typename DestDerived::Scalar,ColMajor,typename DestDerived::StorageIndex>(*x_cs);
|
||||||
cholmod_free_sparse(&x_cs, &m_cholmod);
|
internal::cm_free_sparse<StorageIndex>(x_cs, m_cholmod);
|
||||||
}
|
}
|
||||||
#endif // EIGEN_PARSED_BY_DOXYGEN
|
#endif // EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,413 @@
|
||||||
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
|
// for linear algebra.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2017 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the Mozilla
|
||||||
|
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||||
|
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
#ifndef EIGEN_ARITHMETIC_SEQUENCE_H
|
||||||
|
#define EIGEN_ARITHMETIC_SEQUENCE_H
|
||||||
|
|
||||||
|
namespace Eigen {
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
#if (!EIGEN_HAS_CXX11) || !((!EIGEN_COMP_GNUC) || EIGEN_COMP_GNUC>=48)
|
||||||
|
template<typename T> struct aseq_negate {};
|
||||||
|
|
||||||
|
template<> struct aseq_negate<Index> {
|
||||||
|
typedef Index type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<int N> struct aseq_negate<FixedInt<N> > {
|
||||||
|
typedef FixedInt<-N> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Compilation error in the following case:
|
||||||
|
template<> struct aseq_negate<FixedInt<DynamicIndex> > {};
|
||||||
|
|
||||||
|
template<typename FirstType,typename SizeType,typename IncrType,
|
||||||
|
bool FirstIsSymbolic=symbolic::is_symbolic<FirstType>::value,
|
||||||
|
bool SizeIsSymbolic =symbolic::is_symbolic<SizeType>::value>
|
||||||
|
struct aseq_reverse_first_type {
|
||||||
|
typedef Index type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename FirstType,typename SizeType,typename IncrType>
|
||||||
|
struct aseq_reverse_first_type<FirstType,SizeType,IncrType,true,true> {
|
||||||
|
typedef symbolic::AddExpr<FirstType,
|
||||||
|
symbolic::ProductExpr<symbolic::AddExpr<SizeType,symbolic::ValueExpr<FixedInt<-1> > >,
|
||||||
|
symbolic::ValueExpr<IncrType> >
|
||||||
|
> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename SizeType,typename IncrType,typename EnableIf = void>
|
||||||
|
struct aseq_reverse_first_type_aux {
|
||||||
|
typedef Index type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename SizeType,typename IncrType>
|
||||||
|
struct aseq_reverse_first_type_aux<SizeType,IncrType,typename internal::enable_if<bool((SizeType::value+IncrType::value)|0x1)>::type> {
|
||||||
|
typedef FixedInt<(SizeType::value-1)*IncrType::value> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename FirstType,typename SizeType,typename IncrType>
|
||||||
|
struct aseq_reverse_first_type<FirstType,SizeType,IncrType,true,false> {
|
||||||
|
typedef typename aseq_reverse_first_type_aux<SizeType,IncrType>::type Aux;
|
||||||
|
typedef symbolic::AddExpr<FirstType,symbolic::ValueExpr<Aux> > type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename FirstType,typename SizeType,typename IncrType>
|
||||||
|
struct aseq_reverse_first_type<FirstType,SizeType,IncrType,false,true> {
|
||||||
|
typedef symbolic::AddExpr<symbolic::ProductExpr<symbolic::AddExpr<SizeType,symbolic::ValueExpr<FixedInt<-1> > >,
|
||||||
|
symbolic::ValueExpr<IncrType> >,
|
||||||
|
symbolic::ValueExpr<> > type;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Helper to cleanup the type of the increment:
|
||||||
|
template<typename T> struct cleanup_seq_incr {
|
||||||
|
typedef typename cleanup_index_type<T,DynamicIndex>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
// seq(first,last,incr) and seqN(first,size,incr)
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template<typename FirstType=Index,typename SizeType=Index,typename IncrType=internal::FixedInt<1> >
|
||||||
|
class ArithmeticSequence;
|
||||||
|
|
||||||
|
template<typename FirstType,typename SizeType,typename IncrType>
|
||||||
|
ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,
|
||||||
|
typename internal::cleanup_index_type<SizeType>::type,
|
||||||
|
typename internal::cleanup_seq_incr<IncrType>::type >
|
||||||
|
seqN(FirstType first, SizeType size, IncrType incr);
|
||||||
|
|
||||||
|
/** \class ArithmeticSequence
|
||||||
|
* \ingroup Core_Module
|
||||||
|
*
|
||||||
|
* This class represents an arithmetic progression \f$ a_0, a_1, a_2, ..., a_{n-1}\f$ defined by
|
||||||
|
* its \em first value \f$ a_0 \f$, its \em size (aka length) \em n, and the \em increment (aka stride)
|
||||||
|
* that is equal to \f$ a_{i+1}-a_{i}\f$ for any \em i.
|
||||||
|
*
|
||||||
|
* It is internally used as the return type of the Eigen::seq and Eigen::seqN functions, and as the input arguments
|
||||||
|
* of DenseBase::operator()(const RowIndices&, const ColIndices&), and most of the time this is the
|
||||||
|
* only way it is used.
|
||||||
|
*
|
||||||
|
* \tparam FirstType type of the first element, usually an Index,
|
||||||
|
* but internally it can be a symbolic expression
|
||||||
|
* \tparam SizeType type representing the size of the sequence, usually an Index
|
||||||
|
* or a compile time integral constant. Internally, it can also be a symbolic expression
|
||||||
|
* \tparam IncrType type of the increment, can be a runtime Index, or a compile time integral constant (default is compile-time 1)
|
||||||
|
*
|
||||||
|
* \sa Eigen::seq, Eigen::seqN, DenseBase::operator()(const RowIndices&, const ColIndices&), class IndexedView
|
||||||
|
*/
|
||||||
|
template<typename FirstType,typename SizeType,typename IncrType>
|
||||||
|
class ArithmeticSequence
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ArithmeticSequence(FirstType first, SizeType size) : m_first(first), m_size(size) {}
|
||||||
|
ArithmeticSequence(FirstType first, SizeType size, IncrType incr) : m_first(first), m_size(size), m_incr(incr) {}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SizeAtCompileTime = internal::get_fixed_value<SizeType>::value,
|
||||||
|
IncrAtCompileTime = internal::get_fixed_value<IncrType,DynamicIndex>::value
|
||||||
|
};
|
||||||
|
|
||||||
|
/** \returns the size, i.e., number of elements, of the sequence */
|
||||||
|
Index size() const { return m_size; }
|
||||||
|
|
||||||
|
/** \returns the first element \f$ a_0 \f$ in the sequence */
|
||||||
|
Index first() const { return m_first; }
|
||||||
|
|
||||||
|
/** \returns the value \f$ a_i \f$ at index \a i in the sequence. */
|
||||||
|
Index operator[](Index i) const { return m_first + i * m_incr; }
|
||||||
|
|
||||||
|
const FirstType& firstObject() const { return m_first; }
|
||||||
|
const SizeType& sizeObject() const { return m_size; }
|
||||||
|
const IncrType& incrObject() const { return m_incr; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
FirstType m_first;
|
||||||
|
SizeType m_size;
|
||||||
|
IncrType m_incr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
#if EIGEN_HAS_CXX11 && ((!EIGEN_COMP_GNUC) || EIGEN_COMP_GNUC>=48)
|
||||||
|
auto reverse() const -> decltype(Eigen::seqN(m_first+(m_size+fix<-1>())*m_incr,m_size,-m_incr)) {
|
||||||
|
return seqN(m_first+(m_size+fix<-1>())*m_incr,m_size,-m_incr);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
protected:
|
||||||
|
typedef typename internal::aseq_negate<IncrType>::type ReverseIncrType;
|
||||||
|
typedef typename internal::aseq_reverse_first_type<FirstType,SizeType,IncrType>::type ReverseFirstType;
|
||||||
|
public:
|
||||||
|
ArithmeticSequence<ReverseFirstType,SizeType,ReverseIncrType>
|
||||||
|
reverse() const {
|
||||||
|
return seqN(m_first+(m_size+fix<-1>())*m_incr,m_size,-m_incr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/** \returns an ArithmeticSequence starting at \a first, of length \a size, and increment \a incr
|
||||||
|
*
|
||||||
|
* \sa seqN(FirstType,SizeType), seq(FirstType,LastType,IncrType) */
|
||||||
|
template<typename FirstType,typename SizeType,typename IncrType>
|
||||||
|
ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,typename internal::cleanup_index_type<SizeType>::type,typename internal::cleanup_seq_incr<IncrType>::type >
|
||||||
|
seqN(FirstType first, SizeType size, IncrType incr) {
|
||||||
|
return ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,typename internal::cleanup_index_type<SizeType>::type,typename internal::cleanup_seq_incr<IncrType>::type>(first,size,incr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \returns an ArithmeticSequence starting at \a first, of length \a size, and unit increment
|
||||||
|
*
|
||||||
|
* \sa seqN(FirstType,SizeType,IncrType), seq(FirstType,LastType) */
|
||||||
|
template<typename FirstType,typename SizeType>
|
||||||
|
ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,typename internal::cleanup_index_type<SizeType>::type >
|
||||||
|
seqN(FirstType first, SizeType size) {
|
||||||
|
return ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,typename internal::cleanup_index_type<SizeType>::type>(first,size);
|
||||||
|
}
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
#if EIGEN_HAS_CXX11
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // EIGEN_HAS_CXX11
|
||||||
|
|
||||||
|
template<typename FirstType,typename LastType>
|
||||||
|
typename internal::enable_if<!(symbolic::is_symbolic<FirstType>::value || symbolic::is_symbolic<LastType>::value),
|
||||||
|
ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,Index> >::type
|
||||||
|
seq(FirstType f, LastType l)
|
||||||
|
{
|
||||||
|
return seqN(typename internal::cleanup_index_type<FirstType>::type(f),
|
||||||
|
Index((typename internal::cleanup_index_type<LastType>::type(l)-typename internal::cleanup_index_type<FirstType>::type(f)+fix<1>())));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FirstTypeDerived,typename LastType>
|
||||||
|
typename internal::enable_if<!symbolic::is_symbolic<LastType>::value,
|
||||||
|
ArithmeticSequence<FirstTypeDerived, symbolic::AddExpr<symbolic::AddExpr<symbolic::NegateExpr<FirstTypeDerived>,symbolic::ValueExpr<> >,
|
||||||
|
symbolic::ValueExpr<internal::FixedInt<1> > > > >::type
|
||||||
|
seq(const symbolic::BaseExpr<FirstTypeDerived> &f, LastType l)
|
||||||
|
{
|
||||||
|
return seqN(f.derived(),(typename internal::cleanup_index_type<LastType>::type(l)-f.derived()+fix<1>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FirstType,typename LastTypeDerived>
|
||||||
|
typename internal::enable_if<!symbolic::is_symbolic<FirstType>::value,
|
||||||
|
ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,
|
||||||
|
symbolic::AddExpr<symbolic::AddExpr<LastTypeDerived,symbolic::ValueExpr<> >,
|
||||||
|
symbolic::ValueExpr<internal::FixedInt<1> > > > >::type
|
||||||
|
seq(FirstType f, const symbolic::BaseExpr<LastTypeDerived> &l)
|
||||||
|
{
|
||||||
|
return seqN(typename internal::cleanup_index_type<FirstType>::type(f),(l.derived()-typename internal::cleanup_index_type<FirstType>::type(f)+fix<1>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FirstTypeDerived,typename LastTypeDerived>
|
||||||
|
ArithmeticSequence<FirstTypeDerived,
|
||||||
|
symbolic::AddExpr<symbolic::AddExpr<LastTypeDerived,symbolic::NegateExpr<FirstTypeDerived> >,symbolic::ValueExpr<internal::FixedInt<1> > > >
|
||||||
|
seq(const symbolic::BaseExpr<FirstTypeDerived> &f, const symbolic::BaseExpr<LastTypeDerived> &l)
|
||||||
|
{
|
||||||
|
return seqN(f.derived(),(l.derived()-f.derived()+fix<1>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename FirstType,typename LastType, typename IncrType>
|
||||||
|
typename internal::enable_if<!(symbolic::is_symbolic<FirstType>::value || symbolic::is_symbolic<LastType>::value),
|
||||||
|
ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,Index,typename internal::cleanup_seq_incr<IncrType>::type> >::type
|
||||||
|
seq(FirstType f, LastType l, IncrType incr)
|
||||||
|
{
|
||||||
|
typedef typename internal::cleanup_seq_incr<IncrType>::type CleanedIncrType;
|
||||||
|
return seqN(typename internal::cleanup_index_type<FirstType>::type(f),
|
||||||
|
Index((typename internal::cleanup_index_type<LastType>::type(l)-typename internal::cleanup_index_type<FirstType>::type(f)+CleanedIncrType(incr))/CleanedIncrType(incr)), incr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FirstTypeDerived,typename LastType, typename IncrType>
|
||||||
|
typename internal::enable_if<!symbolic::is_symbolic<LastType>::value,
|
||||||
|
ArithmeticSequence<FirstTypeDerived,
|
||||||
|
symbolic::QuotientExpr<symbolic::AddExpr<symbolic::AddExpr<symbolic::NegateExpr<FirstTypeDerived>,
|
||||||
|
symbolic::ValueExpr<> >,
|
||||||
|
symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
|
||||||
|
symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
|
||||||
|
typename internal::cleanup_seq_incr<IncrType>::type> >::type
|
||||||
|
seq(const symbolic::BaseExpr<FirstTypeDerived> &f, LastType l, IncrType incr)
|
||||||
|
{
|
||||||
|
typedef typename internal::cleanup_seq_incr<IncrType>::type CleanedIncrType;
|
||||||
|
return seqN(f.derived(),(typename internal::cleanup_index_type<LastType>::type(l)-f.derived()+CleanedIncrType(incr))/CleanedIncrType(incr), incr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FirstType,typename LastTypeDerived, typename IncrType>
|
||||||
|
typename internal::enable_if<!symbolic::is_symbolic<FirstType>::value,
|
||||||
|
ArithmeticSequence<typename internal::cleanup_index_type<FirstType>::type,
|
||||||
|
symbolic::QuotientExpr<symbolic::AddExpr<symbolic::AddExpr<LastTypeDerived,symbolic::ValueExpr<> >,
|
||||||
|
symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
|
||||||
|
symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
|
||||||
|
typename internal::cleanup_seq_incr<IncrType>::type> >::type
|
||||||
|
seq(FirstType f, const symbolic::BaseExpr<LastTypeDerived> &l, IncrType incr)
|
||||||
|
{
|
||||||
|
typedef typename internal::cleanup_seq_incr<IncrType>::type CleanedIncrType;
|
||||||
|
return seqN(typename internal::cleanup_index_type<FirstType>::type(f),
|
||||||
|
(l.derived()-typename internal::cleanup_index_type<FirstType>::type(f)+CleanedIncrType(incr))/CleanedIncrType(incr), incr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FirstTypeDerived,typename LastTypeDerived, typename IncrType>
|
||||||
|
ArithmeticSequence<FirstTypeDerived,
|
||||||
|
symbolic::QuotientExpr<symbolic::AddExpr<symbolic::AddExpr<LastTypeDerived,
|
||||||
|
symbolic::NegateExpr<FirstTypeDerived> >,
|
||||||
|
symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
|
||||||
|
symbolic::ValueExpr<typename internal::cleanup_seq_incr<IncrType>::type> >,
|
||||||
|
typename internal::cleanup_seq_incr<IncrType>::type>
|
||||||
|
seq(const symbolic::BaseExpr<FirstTypeDerived> &f, const symbolic::BaseExpr<LastTypeDerived> &l, IncrType incr)
|
||||||
|
{
|
||||||
|
typedef typename internal::cleanup_seq_incr<IncrType>::type CleanedIncrType;
|
||||||
|
return seqN(f.derived(),(l.derived()-f.derived()+CleanedIncrType(incr))/CleanedIncrType(incr), incr);
|
||||||
|
}
|
||||||
|
#endif // EIGEN_HAS_CXX11
|
||||||
|
|
||||||
|
#endif // EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
|
||||||
|
|
||||||
|
#if EIGEN_HAS_CXX11 || defined(EIGEN_PARSED_BY_DOXYGEN)
|
||||||
|
/** \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
|
||||||
|
*
|
||||||
|
* \sa lastN(SizeType), seqN(FirstType,SizeType), seq(FirstType,LastType,IncrType) */
|
||||||
|
template<typename SizeType,typename IncrType>
|
||||||
|
auto lastN(SizeType size, IncrType incr)
|
||||||
|
-> decltype(seqN(Eigen::last-(size-fix<1>())*incr, size, incr))
|
||||||
|
{
|
||||||
|
return seqN(Eigen::last-(size-fix<1>())*incr, size, incr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \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::last+fix<1>()-size, size))
|
||||||
|
{
|
||||||
|
return seqN(Eigen::last+fix<1>()-size, size);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// Convert a symbolic span into a usable one (i.e., remove last/end "keywords")
|
||||||
|
template<typename T>
|
||||||
|
struct make_size_type {
|
||||||
|
typedef typename internal::conditional<symbolic::is_symbolic<T>::value, Index, T>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename FirstType,typename SizeType,typename IncrType,int XprSize>
|
||||||
|
struct IndexedViewCompatibleType<ArithmeticSequence<FirstType,SizeType,IncrType>, XprSize> {
|
||||||
|
typedef ArithmeticSequence<Index,typename make_size_type<SizeType>::type,IncrType> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename FirstType,typename SizeType,typename IncrType>
|
||||||
|
ArithmeticSequence<Index,typename make_size_type<SizeType>::type,IncrType>
|
||||||
|
makeIndexedViewCompatible(const ArithmeticSequence<FirstType,SizeType,IncrType>& ids, Index size,SpecializedType) {
|
||||||
|
return ArithmeticSequence<Index,typename make_size_type<SizeType>::type,IncrType>(
|
||||||
|
eval_expr_given_size(ids.firstObject(),size),eval_expr_given_size(ids.sizeObject(),size),ids.incrObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FirstType,typename SizeType,typename IncrType>
|
||||||
|
struct get_compile_time_incr<ArithmeticSequence<FirstType,SizeType,IncrType> > {
|
||||||
|
enum { value = get_fixed_value<IncrType,DynamicIndex>::value };
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace internal
|
||||||
|
|
||||||
|
/** \namespace Eigen::indexing
|
||||||
|
* \ingroup Core_Module
|
||||||
|
*
|
||||||
|
* The sole purpose of this namespace is to be able to import all functions
|
||||||
|
* and symbols that are expected to be used within operator() for indexing
|
||||||
|
* and slicing. If you already imported the whole Eigen namespace:
|
||||||
|
* \code using namespace Eigen; \endcode
|
||||||
|
* then you are already all set. Otherwise, if you don't want/cannot import
|
||||||
|
* the whole Eigen namespace, the following line:
|
||||||
|
* \code using namespace Eigen::indexing; \endcode
|
||||||
|
* is equivalent to:
|
||||||
|
* \code
|
||||||
|
using Eigen::all;
|
||||||
|
using Eigen::seq;
|
||||||
|
using Eigen::seqN;
|
||||||
|
using Eigen::lastN; // c++11 only
|
||||||
|
using Eigen::last;
|
||||||
|
using Eigen::lastp1;
|
||||||
|
using Eigen::fix;
|
||||||
|
\endcode
|
||||||
|
*/
|
||||||
|
namespace indexing {
|
||||||
|
using Eigen::all;
|
||||||
|
using Eigen::seq;
|
||||||
|
using Eigen::seqN;
|
||||||
|
#if EIGEN_HAS_CXX11
|
||||||
|
using Eigen::lastN;
|
||||||
|
#endif
|
||||||
|
using Eigen::last;
|
||||||
|
using Eigen::lastp1;
|
||||||
|
using Eigen::fix;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
#endif // EIGEN_ARITHMETIC_SEQUENCE_H
|
||||||
|
|
@ -157,11 +157,50 @@ class Array
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
Array& operator=(Array&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_assignable<Scalar>::value)
|
Array& operator=(Array&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_assignable<Scalar>::value)
|
||||||
{
|
{
|
||||||
other.swap(*this);
|
Base::operator=(std::move(other));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if EIGEN_HAS_CXX11
|
||||||
|
/** \copydoc PlainObjectBase(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args)
|
||||||
|
*
|
||||||
|
* Example: \include Array_variadic_ctor_cxx11.cpp
|
||||||
|
* Output: \verbinclude Array_variadic_ctor_cxx11.out
|
||||||
|
*
|
||||||
|
* \sa Array(const std::initializer_list<std::initializer_list<Scalar>>&)
|
||||||
|
* \sa Array(const Scalar&), Array(const Scalar&,const Scalar&)
|
||||||
|
*/
|
||||||
|
template <typename... ArgTypes>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args)
|
||||||
|
: Base(a0, a1, a2, a3, args...) {}
|
||||||
|
|
||||||
|
/** \brief Constructs an array and initializes it from the coefficients given as initializer-lists grouped by row. \cpp11
|
||||||
|
*
|
||||||
|
* In the general case, the constructor takes a list of rows, each row being represented as a list of coefficients:
|
||||||
|
*
|
||||||
|
* Example: \include Array_initializer_list_23_cxx11.cpp
|
||||||
|
* Output: \verbinclude Array_initializer_list_23_cxx11.out
|
||||||
|
*
|
||||||
|
* Each of the inner initializer lists must contain the exact same number of elements, otherwise an assertion is triggered.
|
||||||
|
*
|
||||||
|
* In the case of a compile-time column 1D array, implicit transposition from a single row is allowed.
|
||||||
|
* Therefore <code> Array<int,Dynamic,1>{{1,2,3,4,5}}</code> is legal and the more verbose syntax
|
||||||
|
* <code>Array<int,Dynamic,1>{{1},{2},{3},{4},{5}}</code> can be avoided:
|
||||||
|
*
|
||||||
|
* Example: \include Array_initializer_list_vector_cxx11.cpp
|
||||||
|
* Output: \verbinclude Array_initializer_list_vector_cxx11.out
|
||||||
|
*
|
||||||
|
* In the case of fixed-sized arrays, the initializer list sizes must exactly match the array sizes,
|
||||||
|
* and implicit transposition is allowed for compile-time 1D arrays only.
|
||||||
|
*
|
||||||
|
* \sa Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args)
|
||||||
|
*/
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE Array(const std::initializer_list<std::initializer_list<Scalar>>& list) : Base(list) {}
|
||||||
|
#endif // end EIGEN_HAS_CXX11
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
template<typename T>
|
template<typename T>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
|
|
@ -178,6 +217,7 @@ class Array
|
||||||
Base::_check_template_params();
|
Base::_check_template_params();
|
||||||
this->template _init2<T0,T1>(val0, val1);
|
this->template _init2<T0,T1>(val0, val1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/** \brief Constructs a fixed-sized array initialized with coefficients starting at \a data */
|
/** \brief Constructs a fixed-sized array initialized with coefficients starting at \a data */
|
||||||
EIGEN_DEVICE_FUNC explicit Array(const Scalar *data);
|
EIGEN_DEVICE_FUNC explicit Array(const Scalar *data);
|
||||||
|
|
@ -189,7 +229,8 @@ class Array
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
EIGEN_STRONG_INLINE explicit Array(Index dim);
|
EIGEN_STRONG_INLINE explicit Array(Index dim);
|
||||||
/** constructs an initialized 1x1 Array with the given coefficient */
|
/** constructs an initialized 1x1 Array with the given coefficient
|
||||||
|
* \sa const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args */
|
||||||
Array(const Scalar& value);
|
Array(const Scalar& value);
|
||||||
/** constructs an uninitialized array with \a rows rows and \a cols columns.
|
/** constructs an uninitialized array with \a rows rows and \a cols columns.
|
||||||
*
|
*
|
||||||
|
|
@ -197,11 +238,14 @@ class Array
|
||||||
* it is redundant to pass these parameters, so one should use the default constructor
|
* it is redundant to pass these parameters, so one should use the default constructor
|
||||||
* Array() instead. */
|
* Array() instead. */
|
||||||
Array(Index rows, Index cols);
|
Array(Index rows, Index cols);
|
||||||
/** constructs an initialized 2D vector with given coefficients */
|
/** constructs an initialized 2D vector with given coefficients
|
||||||
|
* \sa Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args) */
|
||||||
Array(const Scalar& val0, const Scalar& val1);
|
Array(const Scalar& val0, const Scalar& val1);
|
||||||
#endif
|
#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_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2)
|
EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2)
|
||||||
{
|
{
|
||||||
|
|
@ -211,7 +255,9 @@ class Array
|
||||||
m_storage.data()[1] = val1;
|
m_storage.data()[1] = val1;
|
||||||
m_storage.data()[2] = val2;
|
m_storage.data()[2] = val2;
|
||||||
}
|
}
|
||||||
/** constructs an initialized 4D vector with given coefficients */
|
/** constructs an initialized 4D vector with given coefficients
|
||||||
|
* \sa Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args)
|
||||||
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2, const Scalar& val3)
|
EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2, const Scalar& val3)
|
||||||
{
|
{
|
||||||
|
|
@ -242,8 +288,10 @@ class Array
|
||||||
: Base(other.derived())
|
: Base(other.derived())
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline Index innerStride() const { return 1; }
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
EIGEN_DEVICE_FUNC inline Index outerStride() const { return this->innerSize(); }
|
inline Index innerStride() const EIGEN_NOEXCEPT{ return 1; }
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
|
inline Index outerStride() const EIGEN_NOEXCEPT { return this->innerSize(); }
|
||||||
|
|
||||||
#ifdef EIGEN_ARRAY_PLUGIN
|
#ifdef EIGEN_ARRAY_PLUGIN
|
||||||
#include EIGEN_ARRAY_PLUGIN
|
#include EIGEN_ARRAY_PLUGIN
|
||||||
|
|
@ -258,7 +306,7 @@ class Array
|
||||||
/** \defgroup arraytypedefs Global array typedefs
|
/** \defgroup arraytypedefs Global array typedefs
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
*
|
*
|
||||||
* Eigen defines several typedef shortcuts for most common 1D and 2D array types.
|
* %Eigen defines several typedef shortcuts for most common 1D and 2D array types.
|
||||||
*
|
*
|
||||||
* The general patterns are the following:
|
* The general patterns are the following:
|
||||||
*
|
*
|
||||||
|
|
@ -271,6 +319,12 @@ class Array
|
||||||
* There are also \c ArraySizeType which are self-explanatory. For example, \c Array4cf is
|
* There are also \c ArraySizeType which are self-explanatory. For example, \c Array4cf is
|
||||||
* a fixed-size 1D array of 4 complex floats.
|
* a fixed-size 1D array of 4 complex floats.
|
||||||
*
|
*
|
||||||
|
* With \cpp11, template alias are also defined for common sizes.
|
||||||
|
* They follow the same pattern as above except that the scalar type suffix is replaced by a
|
||||||
|
* template parameter, i.e.:
|
||||||
|
* - `ArrayRowsCols<Type>` where `Rows` and `Cols` can be \c 2,\c 3,\c 4, or \c X for fixed or dynamic size.
|
||||||
|
* - `ArraySize<Type>` where `Size` can be \c 2,\c 3,\c 4 or \c X for fixed or dynamic size 1D arrays.
|
||||||
|
*
|
||||||
* \sa class Array
|
* \sa class Array
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -303,8 +357,42 @@ 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
|
||||||
|
|
||||||
#undef EIGEN_MAKE_ARRAY_TYPEDEFS_LARGE
|
#if EIGEN_HAS_CXX11
|
||||||
|
|
||||||
|
#define EIGEN_MAKE_ARRAY_TYPEDEFS(Size, SizeSuffix) \
|
||||||
|
/** \ingroup arraytypedefs */ \
|
||||||
|
/** \brief \cpp11 */ \
|
||||||
|
template <typename Type> \
|
||||||
|
using Array##SizeSuffix##SizeSuffix = Array<Type, Size, Size>; \
|
||||||
|
/** \ingroup arraytypedefs */ \
|
||||||
|
/** \brief \cpp11 */ \
|
||||||
|
template <typename Type> \
|
||||||
|
using Array##SizeSuffix = Array<Type, Size, 1>;
|
||||||
|
|
||||||
|
#define EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Size) \
|
||||||
|
/** \ingroup arraytypedefs */ \
|
||||||
|
/** \brief \cpp11 */ \
|
||||||
|
template <typename Type> \
|
||||||
|
using Array##Size##X = Array<Type, Size, Dynamic>; \
|
||||||
|
/** \ingroup arraytypedefs */ \
|
||||||
|
/** \brief \cpp11 */ \
|
||||||
|
template <typename Type> \
|
||||||
|
using Array##X##Size = Array<Type, Dynamic, Size>;
|
||||||
|
|
||||||
|
EIGEN_MAKE_ARRAY_TYPEDEFS(2, 2)
|
||||||
|
EIGEN_MAKE_ARRAY_TYPEDEFS(3, 3)
|
||||||
|
EIGEN_MAKE_ARRAY_TYPEDEFS(4, 4)
|
||||||
|
EIGEN_MAKE_ARRAY_TYPEDEFS(Dynamic, X)
|
||||||
|
EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(2)
|
||||||
|
EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(3)
|
||||||
|
EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(4)
|
||||||
|
|
||||||
|
#undef EIGEN_MAKE_ARRAY_TYPEDEFS
|
||||||
|
#undef EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS
|
||||||
|
|
||||||
|
#endif // EIGEN_HAS_CXX11
|
||||||
|
|
||||||
#define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \
|
#define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \
|
||||||
using Eigen::Matrix##SizeSuffix##TypeSuffix; \
|
using Eigen::Matrix##SizeSuffix##TypeSuffix; \
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ template<typename Derived> class ArrayBase
|
||||||
using Base::coeff;
|
using Base::coeff;
|
||||||
using Base::coeffRef;
|
using Base::coeffRef;
|
||||||
using Base::lazyAssign;
|
using Base::lazyAssign;
|
||||||
|
using Base::operator-;
|
||||||
using Base::operator=;
|
using Base::operator=;
|
||||||
using Base::operator+=;
|
using Base::operator+=;
|
||||||
using Base::operator-=;
|
using Base::operator-=;
|
||||||
|
|
@ -88,7 +89,6 @@ template<typename Derived> class ArrayBase
|
||||||
|
|
||||||
#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::ArrayBase
|
#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::ArrayBase
|
||||||
#define EIGEN_DOC_UNARY_ADDONS(X,Y)
|
#define EIGEN_DOC_UNARY_ADDONS(X,Y)
|
||||||
# include "../plugins/CommonCwiseUnaryOps.h"
|
|
||||||
# include "../plugins/MatrixCwiseUnaryOps.h"
|
# include "../plugins/MatrixCwiseUnaryOps.h"
|
||||||
# include "../plugins/ArrayCwiseUnaryOps.h"
|
# include "../plugins/ArrayCwiseUnaryOps.h"
|
||||||
# include "../plugins/CommonCwiseBinaryOps.h"
|
# include "../plugins/CommonCwiseBinaryOps.h"
|
||||||
|
|
@ -153,8 +153,8 @@ template<typename Derived> class ArrayBase
|
||||||
// inline void evalTo(Dest& dst) const { dst = matrix(); }
|
// inline void evalTo(Dest& dst) const { dst = matrix(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEFAULT_COPY_CONSTRUCTOR(ArrayBase)
|
||||||
ArrayBase() : Base() {}
|
EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(ArrayBase)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ArrayBase(Index);
|
explicit ArrayBase(Index);
|
||||||
|
|
|
||||||
|
|
@ -60,14 +60,14 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
explicit EIGEN_STRONG_INLINE ArrayWrapper(ExpressionType& matrix) : m_expression(matrix) {}
|
explicit EIGEN_STRONG_INLINE ArrayWrapper(ExpressionType& matrix) : m_expression(matrix) {}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index rows() const { return m_expression.rows(); }
|
inline Index rows() const EIGEN_NOEXCEPT { return m_expression.rows(); }
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index cols() const { return m_expression.cols(); }
|
inline Index cols() const EIGEN_NOEXCEPT { return m_expression.cols(); }
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index outerStride() const { return m_expression.outerStride(); }
|
inline Index outerStride() const EIGEN_NOEXCEPT { return m_expression.outerStride(); }
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index innerStride() const { return m_expression.innerStride(); }
|
inline Index innerStride() const EIGEN_NOEXCEPT { return m_expression.innerStride(); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
|
inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
|
||||||
|
|
@ -90,8 +90,8 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline void evalTo(Dest& dst) const { dst = m_expression; }
|
inline void evalTo(Dest& dst) const { dst = m_expression; }
|
||||||
|
|
||||||
const typename internal::remove_all<NestedExpressionType>::type&
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
|
const typename internal::remove_all<NestedExpressionType>::type&
|
||||||
nestedExpression() const
|
nestedExpression() const
|
||||||
{
|
{
|
||||||
return m_expression;
|
return m_expression;
|
||||||
|
|
@ -158,14 +158,14 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
explicit inline MatrixWrapper(ExpressionType& matrix) : m_expression(matrix) {}
|
explicit inline MatrixWrapper(ExpressionType& matrix) : m_expression(matrix) {}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index rows() const { return m_expression.rows(); }
|
inline Index rows() const EIGEN_NOEXCEPT { return m_expression.rows(); }
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index cols() const { return m_expression.cols(); }
|
inline Index cols() const EIGEN_NOEXCEPT { return m_expression.cols(); }
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index outerStride() const { return m_expression.outerStride(); }
|
inline Index outerStride() const EIGEN_NOEXCEPT { return m_expression.outerStride(); }
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index innerStride() const { return m_expression.innerStride(); }
|
inline Index innerStride() const EIGEN_NOEXCEPT { return m_expression.innerStride(); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
|
inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ namespace Eigen {
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_STRONG_INLINE Derived& DenseBase<Derived>
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>
|
||||||
::lazyAssign(const DenseBase<OtherDerived>& other)
|
::lazyAssign(const DenseBase<OtherDerived>& other)
|
||||||
{
|
{
|
||||||
enum{
|
enum{
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ namespace internal {
|
||||||
|
|
||||||
// copy_using_evaluator_traits is based on assign_traits
|
// copy_using_evaluator_traits is based on assign_traits
|
||||||
|
|
||||||
template <typename DstEvaluator, typename SrcEvaluator, typename AssignFunc>
|
template <typename DstEvaluator, typename SrcEvaluator, typename AssignFunc, int MaxPacketSize = -1>
|
||||||
struct copy_using_evaluator_traits
|
struct copy_using_evaluator_traits
|
||||||
{
|
{
|
||||||
typedef typename DstEvaluator::XprType Dst;
|
typedef typename DstEvaluator::XprType Dst;
|
||||||
|
|
@ -51,13 +51,15 @@ private:
|
||||||
InnerMaxSize = int(Dst::IsVectorAtCompileTime) ? int(Dst::MaxSizeAtCompileTime)
|
InnerMaxSize = int(Dst::IsVectorAtCompileTime) ? int(Dst::MaxSizeAtCompileTime)
|
||||||
: int(DstFlags)&RowMajorBit ? int(Dst::MaxColsAtCompileTime)
|
: int(DstFlags)&RowMajorBit ? int(Dst::MaxColsAtCompileTime)
|
||||||
: int(Dst::MaxRowsAtCompileTime),
|
: int(Dst::MaxRowsAtCompileTime),
|
||||||
|
RestrictedInnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(InnerSize,MaxPacketSize),
|
||||||
|
RestrictedLinearSize = EIGEN_SIZE_MIN_PREFER_FIXED(Dst::SizeAtCompileTime,MaxPacketSize),
|
||||||
OuterStride = int(outer_stride_at_compile_time<Dst>::ret),
|
OuterStride = int(outer_stride_at_compile_time<Dst>::ret),
|
||||||
MaxSizeAtCompileTime = Dst::SizeAtCompileTime
|
MaxSizeAtCompileTime = Dst::SizeAtCompileTime
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO distinguish between linear traversal and inner-traversals
|
// TODO distinguish between linear traversal and inner-traversals
|
||||||
typedef typename find_best_packet<DstScalar,Dst::SizeAtCompileTime>::type LinearPacketType;
|
typedef typename find_best_packet<DstScalar,RestrictedLinearSize>::type LinearPacketType;
|
||||||
typedef typename find_best_packet<DstScalar,InnerSize>::type InnerPacketType;
|
typedef typename find_best_packet<DstScalar,RestrictedInnerSize>::type InnerPacketType;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
LinearPacketSize = unpacket_traits<LinearPacketType>::size,
|
LinearPacketSize = unpacket_traits<LinearPacketType>::size,
|
||||||
|
|
@ -97,7 +99,8 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
Traversal = int(MayLinearVectorize) && (LinearPacketSize>InnerPacketSize) ? int(LinearVectorizedTraversal)
|
Traversal = int(Dst::SizeAtCompileTime) == 0 ? int(AllAtOnceTraversal) // If compile-size is zero, traversing will fail at compile-time.
|
||||||
|
: (int(MayLinearVectorize) && (LinearPacketSize>InnerPacketSize)) ? int(LinearVectorizedTraversal)
|
||||||
: int(MayInnerVectorize) ? int(InnerVectorizedTraversal)
|
: int(MayInnerVectorize) ? int(InnerVectorizedTraversal)
|
||||||
: int(MayLinearVectorize) ? int(LinearVectorizedTraversal)
|
: int(MayLinearVectorize) ? int(LinearVectorizedTraversal)
|
||||||
: int(MaySliceVectorize) ? int(SliceVectorizedTraversal)
|
: int(MaySliceVectorize) ? int(SliceVectorizedTraversal)
|
||||||
|
|
@ -172,6 +175,8 @@ public:
|
||||||
EIGEN_DEBUG_VAR(MaySliceVectorize)
|
EIGEN_DEBUG_VAR(MaySliceVectorize)
|
||||||
std::cerr << "Traversal" << " = " << Traversal << " (" << demangle_traversal(Traversal) << ")" << std::endl;
|
std::cerr << "Traversal" << " = " << Traversal << " (" << demangle_traversal(Traversal) << ")" << std::endl;
|
||||||
EIGEN_DEBUG_VAR(SrcEvaluator::CoeffReadCost)
|
EIGEN_DEBUG_VAR(SrcEvaluator::CoeffReadCost)
|
||||||
|
EIGEN_DEBUG_VAR(DstEvaluator::CoeffReadCost)
|
||||||
|
EIGEN_DEBUG_VAR(Dst::SizeAtCompileTime)
|
||||||
EIGEN_DEBUG_VAR(UnrollingLimit)
|
EIGEN_DEBUG_VAR(UnrollingLimit)
|
||||||
EIGEN_DEBUG_VAR(MayUnrollCompletely)
|
EIGEN_DEBUG_VAR(MayUnrollCompletely)
|
||||||
EIGEN_DEBUG_VAR(MayUnrollInner)
|
EIGEN_DEBUG_VAR(MayUnrollInner)
|
||||||
|
|
@ -312,6 +317,22 @@ template<typename Kernel,
|
||||||
int Unrolling = Kernel::AssignmentTraits::Unrolling>
|
int Unrolling = Kernel::AssignmentTraits::Unrolling>
|
||||||
struct dense_assignment_loop;
|
struct dense_assignment_loop;
|
||||||
|
|
||||||
|
/************************
|
||||||
|
***** Special Cases *****
|
||||||
|
************************/
|
||||||
|
|
||||||
|
// Zero-sized assignment is a no-op.
|
||||||
|
template<typename Kernel, int Unrolling>
|
||||||
|
struct dense_assignment_loop<Kernel, AllAtOnceTraversal, Unrolling>
|
||||||
|
{
|
||||||
|
EIGEN_DEVICE_FUNC static void EIGEN_STRONG_INLINE run(Kernel& /*kernel*/)
|
||||||
|
{
|
||||||
|
typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
|
||||||
|
EIGEN_STATIC_ASSERT(int(DstXprType::SizeAtCompileTime) == 0,
|
||||||
|
EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/************************
|
/************************
|
||||||
*** Default traversal ***
|
*** Default traversal ***
|
||||||
************************/
|
************************/
|
||||||
|
|
@ -429,7 +450,7 @@ struct dense_assignment_loop<Kernel, LinearVectorizedTraversal, CompleteUnrollin
|
||||||
|
|
||||||
enum { size = DstXprType::SizeAtCompileTime,
|
enum { size = DstXprType::SizeAtCompileTime,
|
||||||
packetSize =unpacket_traits<PacketType>::size,
|
packetSize =unpacket_traits<PacketType>::size,
|
||||||
alignedSize = (size/packetSize)*packetSize };
|
alignedSize = (int(size)/packetSize)*packetSize };
|
||||||
|
|
||||||
copy_using_evaluator_innervec_CompleteUnrolling<Kernel, 0, alignedSize>::run(kernel);
|
copy_using_evaluator_innervec_CompleteUnrolling<Kernel, 0, alignedSize>::run(kernel);
|
||||||
copy_using_evaluator_DefaultTraversal_CompleteUnrolling<Kernel, alignedSize, size>::run(kernel);
|
copy_using_evaluator_DefaultTraversal_CompleteUnrolling<Kernel, alignedSize, size>::run(kernel);
|
||||||
|
|
@ -530,7 +551,7 @@ struct dense_assignment_loop<Kernel, SliceVectorizedTraversal, NoUnrolling>
|
||||||
const Scalar *dst_ptr = kernel.dstDataPtr();
|
const Scalar *dst_ptr = kernel.dstDataPtr();
|
||||||
if((!bool(dstIsAligned)) && (UIntPtr(dst_ptr) % sizeof(Scalar))>0)
|
if((!bool(dstIsAligned)) && (UIntPtr(dst_ptr) % sizeof(Scalar))>0)
|
||||||
{
|
{
|
||||||
// the pointer is not aligend-on scalar, so alignment is not possible
|
// the pointer is not aligned-on scalar, so alignment is not possible
|
||||||
return dense_assignment_loop<Kernel,DefaultTraversal,NoUnrolling>::run(kernel);
|
return dense_assignment_loop<Kernel,DefaultTraversal,NoUnrolling>::run(kernel);
|
||||||
}
|
}
|
||||||
const Index packetAlignedMask = packetSize - 1;
|
const Index packetAlignedMask = packetSize - 1;
|
||||||
|
|
@ -568,14 +589,15 @@ struct dense_assignment_loop<Kernel, SliceVectorizedTraversal, InnerUnrolling>
|
||||||
typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
|
typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
|
||||||
typedef typename Kernel::PacketType PacketType;
|
typedef typename Kernel::PacketType PacketType;
|
||||||
|
|
||||||
enum { size = DstXprType::InnerSizeAtCompileTime,
|
enum { innerSize = DstXprType::InnerSizeAtCompileTime,
|
||||||
packetSize =unpacket_traits<PacketType>::size,
|
packetSize =unpacket_traits<PacketType>::size,
|
||||||
vectorizableSize = (size/packetSize)*packetSize };
|
vectorizableSize = (int(innerSize) / int(packetSize)) * int(packetSize),
|
||||||
|
size = DstXprType::SizeAtCompileTime };
|
||||||
|
|
||||||
for(Index outer = 0; outer < kernel.outerSize(); ++outer)
|
for(Index outer = 0; outer < kernel.outerSize(); ++outer)
|
||||||
{
|
{
|
||||||
copy_using_evaluator_innervec_InnerUnrolling<Kernel, 0, vectorizableSize, 0, 0>::run(kernel, outer);
|
copy_using_evaluator_innervec_InnerUnrolling<Kernel, 0, vectorizableSize, 0, 0>::run(kernel, outer);
|
||||||
copy_using_evaluator_DefaultTraversal_InnerUnrolling<Kernel, vectorizableSize, size>::run(kernel, outer);
|
copy_using_evaluator_DefaultTraversal_InnerUnrolling<Kernel, vectorizableSize, innerSize>::run(kernel, outer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -607,7 +629,8 @@ public:
|
||||||
typedef typename AssignmentTraits::PacketType PacketType;
|
typedef typename AssignmentTraits::PacketType PacketType;
|
||||||
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC generic_dense_assignment_kernel(DstEvaluatorType &dst, const SrcEvaluatorType &src, const Functor &func, DstXprType& dstExpr)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
generic_dense_assignment_kernel(DstEvaluatorType &dst, const SrcEvaluatorType &src, const Functor &func, DstXprType& dstExpr)
|
||||||
: m_dst(dst), m_src(src), m_functor(func), m_dstExpr(dstExpr)
|
: m_dst(dst), m_src(src), m_functor(func), m_dstExpr(dstExpr)
|
||||||
{
|
{
|
||||||
#ifdef EIGEN_DEBUG_ASSIGN
|
#ifdef EIGEN_DEBUG_ASSIGN
|
||||||
|
|
@ -615,15 +638,15 @@ public:
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC Index size() const { return m_dstExpr.size(); }
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index size() const EIGEN_NOEXCEPT { return m_dstExpr.size(); }
|
||||||
EIGEN_DEVICE_FUNC Index innerSize() const { return m_dstExpr.innerSize(); }
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index innerSize() const EIGEN_NOEXCEPT { return m_dstExpr.innerSize(); }
|
||||||
EIGEN_DEVICE_FUNC Index outerSize() const { return m_dstExpr.outerSize(); }
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index outerSize() const EIGEN_NOEXCEPT { return m_dstExpr.outerSize(); }
|
||||||
EIGEN_DEVICE_FUNC Index rows() const { return m_dstExpr.rows(); }
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_dstExpr.rows(); }
|
||||||
EIGEN_DEVICE_FUNC Index cols() const { return m_dstExpr.cols(); }
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_dstExpr.cols(); }
|
||||||
EIGEN_DEVICE_FUNC Index outerStride() const { return m_dstExpr.outerStride(); }
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index outerStride() const EIGEN_NOEXCEPT { return m_dstExpr.outerStride(); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC DstEvaluatorType& dstEvaluator() { return m_dst; }
|
EIGEN_DEVICE_FUNC DstEvaluatorType& dstEvaluator() EIGEN_NOEXCEPT { return m_dst; }
|
||||||
EIGEN_DEVICE_FUNC const SrcEvaluatorType& srcEvaluator() const { return m_src; }
|
EIGEN_DEVICE_FUNC const SrcEvaluatorType& srcEvaluator() const EIGEN_NOEXCEPT { return m_src; }
|
||||||
|
|
||||||
/// Assign src(row,col) to dst(row,col) through the assignment functor.
|
/// Assign src(row,col) to dst(row,col) through the assignment functor.
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(Index row, Index col)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(Index row, Index col)
|
||||||
|
|
@ -697,6 +720,27 @@ protected:
|
||||||
DstXprType& m_dstExpr;
|
DstXprType& m_dstExpr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Special kernel used when computing small products whose operands have dynamic dimensions. It ensures that the
|
||||||
|
// PacketSize used is no larger than 4, thereby increasing the chance that vectorized instructions will be used
|
||||||
|
// when computing the product.
|
||||||
|
|
||||||
|
template<typename DstEvaluatorTypeT, typename SrcEvaluatorTypeT, typename Functor>
|
||||||
|
class restricted_packet_dense_assignment_kernel : public generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, BuiltIn>
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
typedef generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, BuiltIn> Base;
|
||||||
|
public:
|
||||||
|
typedef typename Base::Scalar Scalar;
|
||||||
|
typedef typename Base::DstXprType DstXprType;
|
||||||
|
typedef copy_using_evaluator_traits<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, 4> AssignmentTraits;
|
||||||
|
typedef typename AssignmentTraits::PacketType PacketType;
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC restricted_packet_dense_assignment_kernel(DstEvaluatorTypeT &dst, const SrcEvaluatorTypeT &src, const Functor &func, DstXprType& dstExpr)
|
||||||
|
: Base(dst, src, func, dstExpr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Part 5 : Entry point for dense rectangular assignment
|
* Part 5 : Entry point for dense rectangular assignment
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
@ -741,6 +785,16 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void call_dense_assignment_loop(DstXprType
|
||||||
dense_assignment_loop<Kernel>::run(kernel);
|
dense_assignment_loop<Kernel>::run(kernel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Specialization for filling the destination with a constant value.
|
||||||
|
#ifndef EIGEN_GPU_COMPILE_PHASE
|
||||||
|
template<typename DstXprType>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void call_dense_assignment_loop(DstXprType& dst, const Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<typename DstXprType::Scalar>, DstXprType>& src, const internal::assign_op<typename DstXprType::Scalar,typename DstXprType::Scalar>& func)
|
||||||
|
{
|
||||||
|
resize_if_allowed(dst, src, func);
|
||||||
|
std::fill_n(dst.data(), dst.size(), src.functor()());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename DstXprType, typename SrcXprType>
|
template<typename DstXprType, typename SrcXprType>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void call_dense_assignment_loop(DstXprType& dst, const SrcXprType& src)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void call_dense_assignment_loop(DstXprType& dst, const SrcXprType& src)
|
||||||
{
|
{
|
||||||
|
|
@ -756,7 +810,7 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void call_dense_assignment_loop(DstXprType
|
||||||
// AssignmentKind must define a Kind typedef.
|
// AssignmentKind must define a Kind typedef.
|
||||||
template<typename DstShape, typename SrcShape> struct AssignmentKind;
|
template<typename DstShape, typename SrcShape> struct AssignmentKind;
|
||||||
|
|
||||||
// Assignement kind defined in this file:
|
// Assignment kind defined in this file:
|
||||||
struct Dense2Dense {};
|
struct Dense2Dense {};
|
||||||
struct EigenBase2EigenBase {};
|
struct EigenBase2EigenBase {};
|
||||||
|
|
||||||
|
|
@ -835,6 +889,27 @@ void call_assignment_no_alias(Dst& dst, const Src& src, const Func& func)
|
||||||
|
|
||||||
Assignment<ActualDstTypeCleaned,Src,Func>::run(actualDst, src, func);
|
Assignment<ActualDstTypeCleaned,Src,Func>::run(actualDst, src, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Dst, typename Src, typename Func>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
void call_restricted_packet_assignment_no_alias(Dst& dst, const Src& src, const Func& func)
|
||||||
|
{
|
||||||
|
typedef evaluator<Dst> DstEvaluatorType;
|
||||||
|
typedef evaluator<Src> SrcEvaluatorType;
|
||||||
|
typedef restricted_packet_dense_assignment_kernel<DstEvaluatorType,SrcEvaluatorType,Func> Kernel;
|
||||||
|
|
||||||
|
EIGEN_STATIC_ASSERT_LVALUE(Dst)
|
||||||
|
EIGEN_CHECK_BINARY_COMPATIBILIY(Func,typename Dst::Scalar,typename Src::Scalar);
|
||||||
|
|
||||||
|
SrcEvaluatorType srcEvaluator(src);
|
||||||
|
resize_if_allowed(dst, src, func);
|
||||||
|
|
||||||
|
DstEvaluatorType dstEvaluator(dst);
|
||||||
|
Kernel kernel(dstEvaluator, srcEvaluator, func, dst.const_cast_derived());
|
||||||
|
|
||||||
|
dense_assignment_loop<Kernel>::run(kernel);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Dst, typename Src>
|
template<typename Dst, typename Src>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
void call_assignment_no_alias(Dst& dst, const Src& src)
|
void call_assignment_no_alias(Dst& dst, const Src& src)
|
||||||
|
|
@ -899,7 +974,7 @@ struct Assignment<DstXprType, SrcXprType, Functor, EigenBase2EigenBase, Weak>
|
||||||
src.evalTo(dst);
|
src.evalTo(dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE The following two functions are templated to avoid their instanciation if not needed
|
// NOTE The following two functions are templated to avoid their instantiation if not needed
|
||||||
// This is needed because some expressions supports evalTo only and/or have 'void' as scalar type.
|
// This is needed because some expressions supports evalTo only and/or have 'void' as scalar type.
|
||||||
template<typename SrcScalarType>
|
template<typename SrcScalarType>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
|
|
|
||||||
|
|
@ -68,16 +68,16 @@ class vml_assign_traits
|
||||||
|
|
||||||
#define EIGEN_PP_EXPAND(ARG) ARG
|
#define EIGEN_PP_EXPAND(ARG) ARG
|
||||||
#if !defined (EIGEN_FAST_MATH) || (EIGEN_FAST_MATH != 1)
|
#if !defined (EIGEN_FAST_MATH) || (EIGEN_FAST_MATH != 1)
|
||||||
#define EIGEN_VMLMODE_EXPAND_LA , VML_HA
|
#define EIGEN_VMLMODE_EXPAND_xLA , VML_HA
|
||||||
#else
|
#else
|
||||||
#define EIGEN_VMLMODE_EXPAND_LA , VML_LA
|
#define EIGEN_VMLMODE_EXPAND_xLA , VML_LA
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define EIGEN_VMLMODE_EXPAND__
|
#define EIGEN_VMLMODE_EXPAND_x_
|
||||||
|
|
||||||
#define EIGEN_VMLMODE_PREFIX_LA vm
|
#define EIGEN_VMLMODE_PREFIX_xLA vm
|
||||||
#define EIGEN_VMLMODE_PREFIX__ v
|
#define EIGEN_VMLMODE_PREFIX_x_ v
|
||||||
#define EIGEN_VMLMODE_PREFIX(VMLMODE) EIGEN_CAT(EIGEN_VMLMODE_PREFIX_,VMLMODE)
|
#define EIGEN_VMLMODE_PREFIX(VMLMODE) EIGEN_CAT(EIGEN_VMLMODE_PREFIX_x,VMLMODE)
|
||||||
|
|
||||||
#define EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE, VMLMODE) \
|
#define EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE, VMLMODE) \
|
||||||
template< typename DstXprType, typename SrcXprNested> \
|
template< typename DstXprType, typename SrcXprNested> \
|
||||||
|
|
@ -89,7 +89,7 @@ class vml_assign_traits
|
||||||
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols()); \
|
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols()); \
|
||||||
if(vml_assign_traits<DstXprType,SrcXprNested>::Traversal==LinearTraversal) { \
|
if(vml_assign_traits<DstXprType,SrcXprNested>::Traversal==LinearTraversal) { \
|
||||||
VMLOP(dst.size(), (const VMLTYPE*)src.nestedExpression().data(), \
|
VMLOP(dst.size(), (const VMLTYPE*)src.nestedExpression().data(), \
|
||||||
(VMLTYPE*)dst.data() EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_##VMLMODE) ); \
|
(VMLTYPE*)dst.data() EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_x##VMLMODE) ); \
|
||||||
} else { \
|
} else { \
|
||||||
const Index outerSize = dst.outerSize(); \
|
const Index outerSize = dst.outerSize(); \
|
||||||
for(Index outer = 0; outer < outerSize; ++outer) { \
|
for(Index outer = 0; outer < outerSize; ++outer) { \
|
||||||
|
|
@ -97,7 +97,7 @@ class vml_assign_traits
|
||||||
&(src.nestedExpression().coeffRef(0, outer)); \
|
&(src.nestedExpression().coeffRef(0, outer)); \
|
||||||
EIGENTYPE *dst_ptr = dst.IsRowMajor ? &(dst.coeffRef(outer,0)) : &(dst.coeffRef(0, outer)); \
|
EIGENTYPE *dst_ptr = dst.IsRowMajor ? &(dst.coeffRef(outer,0)) : &(dst.coeffRef(0, outer)); \
|
||||||
VMLOP( dst.innerSize(), (const VMLTYPE*)src_ptr, \
|
VMLOP( dst.innerSize(), (const VMLTYPE*)src_ptr, \
|
||||||
(VMLTYPE*)dst_ptr EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_##VMLMODE)); \
|
(VMLTYPE*)dst_ptr EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_x##VMLMODE)); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
|
@ -152,7 +152,7 @@ EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(ceil, Ceil, _)
|
||||||
if(vml_assign_traits<DstXprType,SrcXprNested>::Traversal==LinearTraversal) \
|
if(vml_assign_traits<DstXprType,SrcXprNested>::Traversal==LinearTraversal) \
|
||||||
{ \
|
{ \
|
||||||
VMLOP( dst.size(), (const VMLTYPE*)src.lhs().data(), exponent, \
|
VMLOP( dst.size(), (const VMLTYPE*)src.lhs().data(), exponent, \
|
||||||
(VMLTYPE*)dst.data() EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_##VMLMODE) ); \
|
(VMLTYPE*)dst.data() EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_x##VMLMODE) ); \
|
||||||
} else { \
|
} else { \
|
||||||
const Index outerSize = dst.outerSize(); \
|
const Index outerSize = dst.outerSize(); \
|
||||||
for(Index outer = 0; outer < outerSize; ++outer) { \
|
for(Index outer = 0; outer < outerSize; ++outer) { \
|
||||||
|
|
@ -160,7 +160,7 @@ EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(ceil, Ceil, _)
|
||||||
&(src.lhs().coeffRef(0, outer)); \
|
&(src.lhs().coeffRef(0, outer)); \
|
||||||
EIGENTYPE *dst_ptr = dst.IsRowMajor ? &(dst.coeffRef(outer,0)) : &(dst.coeffRef(0, outer)); \
|
EIGENTYPE *dst_ptr = dst.IsRowMajor ? &(dst.coeffRef(outer,0)) : &(dst.coeffRef(0, outer)); \
|
||||||
VMLOP( dst.innerSize(), (const VMLTYPE*)src_ptr, exponent, \
|
VMLOP( dst.innerSize(), (const VMLTYPE*)src_ptr, exponent, \
|
||||||
(VMLTYPE*)dst_ptr EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_##VMLMODE)); \
|
(VMLTYPE*)dst_ptr EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_x##VMLMODE)); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ class BandMatrixBase : public EigenBase<Derived>
|
||||||
* \warning the internal storage must be column major. */
|
* \warning the internal storage must be column major. */
|
||||||
inline Block<CoefficientsType,Dynamic,1> col(Index i)
|
inline Block<CoefficientsType,Dynamic,1> col(Index i)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT((Options&RowMajor)==0,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
|
EIGEN_STATIC_ASSERT((int(Options) & int(RowMajor)) == 0, THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
|
||||||
Index start = 0;
|
Index start = 0;
|
||||||
Index len = coeffs().rows();
|
Index len = coeffs().rows();
|
||||||
if (i<=supers())
|
if (i<=supers())
|
||||||
|
|
@ -90,7 +90,7 @@ class BandMatrixBase : public EigenBase<Derived>
|
||||||
|
|
||||||
template<int Index> struct DiagonalIntReturnType {
|
template<int Index> struct DiagonalIntReturnType {
|
||||||
enum {
|
enum {
|
||||||
ReturnOpposite = (Options&SelfAdjoint) && (((Index)>0 && Supers==0) || ((Index)<0 && Subs==0)),
|
ReturnOpposite = (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 = (RowsAtCompileTime==Dynamic || ColsAtCompileTime==Dynamic)
|
DiagonalSize = (RowsAtCompileTime==Dynamic || ColsAtCompileTime==Dynamic)
|
||||||
|
|
@ -192,7 +192,7 @@ struct traits<BandMatrix<_Scalar,_Rows,_Cols,_Supers,_Subs,_Options> >
|
||||||
Options = _Options,
|
Options = _Options,
|
||||||
DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic
|
DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic
|
||||||
};
|
};
|
||||||
typedef Matrix<Scalar,DataRowsAtCompileTime,ColsAtCompileTime,Options&RowMajor?RowMajor:ColMajor> CoefficientsType;
|
typedef Matrix<Scalar, DataRowsAtCompileTime, ColsAtCompileTime, int(Options) & int(RowMajor) ? RowMajor : ColMajor> CoefficientsType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _Scalar, int Rows, int Cols, int Supers, int Subs, int Options>
|
template<typename _Scalar, int Rows, int Cols, int Supers, int Subs, int Options>
|
||||||
|
|
@ -211,16 +211,16 @@ class BandMatrix : public BandMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Sub
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the number of columns */
|
/** \returns the number of columns */
|
||||||
inline Index rows() const { return m_rows.value(); }
|
inline EIGEN_CONSTEXPR Index rows() const { return m_rows.value(); }
|
||||||
|
|
||||||
/** \returns the number of rows */
|
/** \returns the number of rows */
|
||||||
inline Index cols() const { return m_coeffs.cols(); }
|
inline EIGEN_CONSTEXPR Index cols() const { return m_coeffs.cols(); }
|
||||||
|
|
||||||
/** \returns the number of super diagonals */
|
/** \returns the number of super diagonals */
|
||||||
inline Index supers() const { return m_supers.value(); }
|
inline EIGEN_CONSTEXPR Index supers() const { return m_supers.value(); }
|
||||||
|
|
||||||
/** \returns the number of sub diagonals */
|
/** \returns the number of sub diagonals */
|
||||||
inline Index subs() const { return m_subs.value(); }
|
inline EIGEN_CONSTEXPR Index subs() const { return m_subs.value(); }
|
||||||
|
|
||||||
inline const CoefficientsType& coeffs() const { return m_coeffs; }
|
inline const CoefficientsType& coeffs() const { return m_coeffs; }
|
||||||
inline CoefficientsType& coeffs() { return m_coeffs; }
|
inline CoefficientsType& coeffs() { return m_coeffs; }
|
||||||
|
|
@ -275,16 +275,16 @@ class BandMatrixWrapper : public BandMatrixBase<BandMatrixWrapper<_CoefficientsT
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the number of columns */
|
/** \returns the number of columns */
|
||||||
inline Index rows() const { return m_rows.value(); }
|
inline EIGEN_CONSTEXPR Index rows() const { return m_rows.value(); }
|
||||||
|
|
||||||
/** \returns the number of rows */
|
/** \returns the number of rows */
|
||||||
inline Index cols() const { return m_coeffs.cols(); }
|
inline EIGEN_CONSTEXPR Index cols() const { return m_coeffs.cols(); }
|
||||||
|
|
||||||
/** \returns the number of super diagonals */
|
/** \returns the number of super diagonals */
|
||||||
inline Index supers() const { return m_supers.value(); }
|
inline EIGEN_CONSTEXPR Index supers() const { return m_supers.value(); }
|
||||||
|
|
||||||
/** \returns the number of sub diagonals */
|
/** \returns the number of sub diagonals */
|
||||||
inline Index subs() const { return m_subs.value(); }
|
inline EIGEN_CONSTEXPR Index subs() const { return m_subs.value(); }
|
||||||
|
|
||||||
inline const CoefficientsType& coeffs() const { return m_coeffs; }
|
inline const CoefficientsType& coeffs() const { return m_coeffs; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -114,8 +114,8 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> class
|
||||||
|
|
||||||
/** Column or Row constructor
|
/** Column or Row constructor
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
inline Block(XprType& xpr, Index i) : Impl(xpr,i)
|
Block(XprType& xpr, Index i) : Impl(xpr,i)
|
||||||
{
|
{
|
||||||
eigen_assert( (i>=0) && (
|
eigen_assert( (i>=0) && (
|
||||||
((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i<xpr.rows())
|
((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i<xpr.rows())
|
||||||
|
|
@ -124,8 +124,8 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> class
|
||||||
|
|
||||||
/** Fixed-size constructor
|
/** Fixed-size constructor
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
inline Block(XprType& xpr, Index startRow, Index startCol)
|
Block(XprType& xpr, Index startRow, Index startCol)
|
||||||
: Impl(xpr, startRow, startCol)
|
: Impl(xpr, startRow, startCol)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
|
EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
|
||||||
|
|
@ -135,8 +135,8 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> class
|
||||||
|
|
||||||
/** Dynamic-size constructor
|
/** Dynamic-size constructor
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
inline Block(XprType& xpr,
|
Block(XprType& xpr,
|
||||||
Index startRow, Index startCol,
|
Index startRow, Index startCol,
|
||||||
Index blockRows, Index blockCols)
|
Index blockRows, Index blockCols)
|
||||||
: Impl(xpr, startRow, startCol, blockRows, blockCols)
|
: Impl(xpr, startRow, startCol, blockRows, blockCols)
|
||||||
|
|
@ -159,10 +159,10 @@ class BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, Dense>
|
||||||
public:
|
public:
|
||||||
typedef Impl Base;
|
typedef Impl Base;
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl)
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl)
|
||||||
EIGEN_DEVICE_FUNC inline BlockImpl(XprType& xpr, Index i) : Impl(xpr,i) {}
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl(XprType& xpr, Index i) : Impl(xpr,i) {}
|
||||||
EIGEN_DEVICE_FUNC inline BlockImpl(XprType& xpr, Index startRow, Index startCol) : Impl(xpr, startRow, startCol) {}
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl(XprType& xpr, Index startRow, Index startCol) : Impl(xpr, startRow, startCol) {}
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline BlockImpl(XprType& xpr, Index startRow, Index startCol, Index blockRows, Index blockCols)
|
EIGEN_STRONG_INLINE BlockImpl(XprType& xpr, Index startRow, Index startCol, Index blockRows, Index blockCols)
|
||||||
: Impl(xpr, startRow, startCol, blockRows, blockCols) {}
|
: Impl(xpr, startRow, startCol, blockRows, blockCols) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -294,23 +294,23 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool H
|
||||||
EIGEN_DEVICE_FUNC inline Index outerStride() const;
|
EIGEN_DEVICE_FUNC inline Index outerStride() const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
const typename internal::remove_all<XprTypeNested>::type& nestedExpression() const
|
const typename internal::remove_all<XprTypeNested>::type& nestedExpression() const
|
||||||
{
|
{
|
||||||
return m_xpr;
|
return m_xpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
XprType& nestedExpression() { return m_xpr; }
|
XprType& nestedExpression() { return m_xpr; }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
StorageIndex startRow() const
|
StorageIndex startRow() const EIGEN_NOEXCEPT
|
||||||
{
|
{
|
||||||
return m_startRow.value();
|
return m_startRow.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
StorageIndex startCol() const
|
StorageIndex startCol() const EIGEN_NOEXCEPT
|
||||||
{
|
{
|
||||||
return m_startCol.value();
|
return m_startCol.value();
|
||||||
}
|
}
|
||||||
|
|
@ -342,8 +342,8 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
||||||
|
|
||||||
/** Column or Row constructor
|
/** Column or Row constructor
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
inline BlockImpl_dense(XprType& xpr, Index i)
|
BlockImpl_dense(XprType& xpr, Index i)
|
||||||
: Base(xpr.data() + i * ( ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && (!XprTypeIsRowMajor))
|
: Base(xpr.data() + i * ( ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && (!XprTypeIsRowMajor))
|
||||||
|| ((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && ( XprTypeIsRowMajor)) ? xpr.innerStride() : xpr.outerStride()),
|
|| ((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && ( XprTypeIsRowMajor)) ? xpr.innerStride() : xpr.outerStride()),
|
||||||
BlockRows==1 ? 1 : xpr.rows(),
|
BlockRows==1 ? 1 : xpr.rows(),
|
||||||
|
|
@ -357,8 +357,8 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
||||||
|
|
||||||
/** Fixed-size constructor
|
/** Fixed-size constructor
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
|
BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
|
||||||
: Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol)),
|
: Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol)),
|
||||||
m_xpr(xpr), m_startRow(startRow), m_startCol(startCol)
|
m_xpr(xpr), m_startRow(startRow), m_startCol(startCol)
|
||||||
{
|
{
|
||||||
|
|
@ -367,8 +367,8 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
||||||
|
|
||||||
/** Dynamic-size constructor
|
/** Dynamic-size constructor
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
inline BlockImpl_dense(XprType& xpr,
|
BlockImpl_dense(XprType& xpr,
|
||||||
Index startRow, Index startCol,
|
Index startRow, Index startCol,
|
||||||
Index blockRows, Index blockCols)
|
Index blockRows, Index blockCols)
|
||||||
: Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol), blockRows, blockCols),
|
: Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol), blockRows, blockCols),
|
||||||
|
|
@ -377,18 +377,18 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
const typename internal::remove_all<XprTypeNested>::type& nestedExpression() const
|
const typename internal::remove_all<XprTypeNested>::type& nestedExpression() const EIGEN_NOEXCEPT
|
||||||
{
|
{
|
||||||
return m_xpr;
|
return m_xpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
XprType& nestedExpression() { return m_xpr; }
|
XprType& nestedExpression() { return m_xpr; }
|
||||||
|
|
||||||
/** \sa MapBase::innerStride() */
|
/** \sa MapBase::innerStride() */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
inline Index innerStride() const
|
Index innerStride() const EIGEN_NOEXCEPT
|
||||||
{
|
{
|
||||||
return internal::traits<BlockType>::HasSameStorageOrderAsXprType
|
return internal::traits<BlockType>::HasSameStorageOrderAsXprType
|
||||||
? m_xpr.innerStride()
|
? m_xpr.innerStride()
|
||||||
|
|
@ -396,23 +396,19 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \sa MapBase::outerStride() */
|
/** \sa MapBase::outerStride() */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
inline Index outerStride() const
|
Index outerStride() const EIGEN_NOEXCEPT
|
||||||
{
|
{
|
||||||
return m_outerStride;
|
return internal::traits<BlockType>::HasSameStorageOrderAsXprType
|
||||||
|
? m_xpr.outerStride()
|
||||||
|
: m_xpr.innerStride();
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
StorageIndex startRow() const
|
StorageIndex startRow() const EIGEN_NOEXCEPT { return m_startRow.value(); }
|
||||||
{
|
|
||||||
return m_startRow.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
StorageIndex startCol() const
|
StorageIndex startCol() const EIGEN_NOEXCEPT { return m_startCol.value(); }
|
||||||
{
|
|
||||||
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...
|
||||||
|
|
@ -422,8 +418,8 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
/** \internal used by allowAligned() */
|
/** \internal used by allowAligned() */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
inline BlockImpl_dense(XprType& xpr, const Scalar* data, Index blockRows, Index blockCols)
|
BlockImpl_dense(XprType& xpr, const Scalar* data, Index blockRows, Index blockCols)
|
||||||
: Base(data, blockRows, blockCols), m_xpr(xpr)
|
: Base(data, blockRows, blockCols), m_xpr(xpr)
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
|
|
@ -431,7 +427,7 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
m_outerStride = internal::traits<BlockType>::HasSameStorageOrderAsXprType
|
m_outerStride = internal::traits<BlockType>::HasSameStorageOrderAsXprType
|
||||||
|
|
|
||||||
|
|
@ -14,58 +14,56 @@ namespace Eigen {
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template<typename Derived, int UnrollCount>
|
template<typename Derived, int UnrollCount, int Rows>
|
||||||
struct all_unroller
|
struct all_unroller
|
||||||
{
|
{
|
||||||
typedef typename Derived::ExpressionTraits Traits;
|
|
||||||
enum {
|
enum {
|
||||||
col = (UnrollCount-1) / Traits::RowsAtCompileTime,
|
col = (UnrollCount-1) / Rows,
|
||||||
row = (UnrollCount-1) % Traits::RowsAtCompileTime
|
row = (UnrollCount-1) % Rows
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline bool run(const Derived &mat)
|
EIGEN_DEVICE_FUNC static inline bool run(const Derived &mat)
|
||||||
{
|
{
|
||||||
return all_unroller<Derived, UnrollCount-1>::run(mat) && mat.coeff(row, col);
|
return all_unroller<Derived, UnrollCount-1, Rows>::run(mat) && mat.coeff(row, col);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived, int Rows>
|
||||||
struct all_unroller<Derived, 0>
|
struct all_unroller<Derived, 0, Rows>
|
||||||
{
|
{
|
||||||
static inline bool run(const Derived &/*mat*/) { return true; }
|
EIGEN_DEVICE_FUNC static inline bool run(const Derived &/*mat*/) { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived, int Rows>
|
||||||
struct all_unroller<Derived, Dynamic>
|
struct all_unroller<Derived, Dynamic, Rows>
|
||||||
{
|
{
|
||||||
static inline bool run(const Derived &) { return false; }
|
EIGEN_DEVICE_FUNC static inline bool run(const Derived &) { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived, int UnrollCount>
|
template<typename Derived, int UnrollCount, int Rows>
|
||||||
struct any_unroller
|
struct any_unroller
|
||||||
{
|
{
|
||||||
typedef typename Derived::ExpressionTraits Traits;
|
|
||||||
enum {
|
enum {
|
||||||
col = (UnrollCount-1) / Traits::RowsAtCompileTime,
|
col = (UnrollCount-1) / Rows,
|
||||||
row = (UnrollCount-1) % Traits::RowsAtCompileTime
|
row = (UnrollCount-1) % Rows
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline bool run(const Derived &mat)
|
EIGEN_DEVICE_FUNC static inline bool run(const Derived &mat)
|
||||||
{
|
{
|
||||||
return any_unroller<Derived, UnrollCount-1>::run(mat) || mat.coeff(row, col);
|
return any_unroller<Derived, UnrollCount-1, Rows>::run(mat) || mat.coeff(row, col);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived, int Rows>
|
||||||
struct any_unroller<Derived, 0>
|
struct any_unroller<Derived, 0, Rows>
|
||||||
{
|
{
|
||||||
static inline bool run(const Derived & /*mat*/) { return false; }
|
EIGEN_DEVICE_FUNC static inline bool run(const Derived & /*mat*/) { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived, int Rows>
|
||||||
struct any_unroller<Derived, Dynamic>
|
struct any_unroller<Derived, Dynamic, Rows>
|
||||||
{
|
{
|
||||||
static inline bool run(const Derived &) { return false; }
|
EIGEN_DEVICE_FUNC static inline bool run(const Derived &) { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
@ -78,16 +76,16 @@ struct any_unroller<Derived, Dynamic>
|
||||||
* \sa any(), Cwise::operator<()
|
* \sa any(), Cwise::operator<()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline bool DenseBase<Derived>::all() const
|
EIGEN_DEVICE_FUNC inline bool DenseBase<Derived>::all() const
|
||||||
{
|
{
|
||||||
typedef internal::evaluator<Derived> Evaluator;
|
typedef internal::evaluator<Derived> Evaluator;
|
||||||
enum {
|
enum {
|
||||||
unroll = SizeAtCompileTime != Dynamic
|
unroll = SizeAtCompileTime != Dynamic
|
||||||
&& SizeAtCompileTime * (Evaluator::CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
|
&& SizeAtCompileTime * (int(Evaluator::CoeffReadCost) + int(NumTraits<Scalar>::AddCost)) <= EIGEN_UNROLLING_LIMIT
|
||||||
};
|
};
|
||||||
Evaluator evaluator(derived());
|
Evaluator evaluator(derived());
|
||||||
if(unroll)
|
if(unroll)
|
||||||
return internal::all_unroller<Evaluator, unroll ? int(SizeAtCompileTime) : Dynamic>::run(evaluator);
|
return internal::all_unroller<Evaluator, unroll ? int(SizeAtCompileTime) : Dynamic, internal::traits<Derived>::RowsAtCompileTime>::run(evaluator);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(Index j = 0; j < cols(); ++j)
|
for(Index j = 0; j < cols(); ++j)
|
||||||
|
|
@ -102,16 +100,16 @@ inline bool DenseBase<Derived>::all() const
|
||||||
* \sa all()
|
* \sa all()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline bool DenseBase<Derived>::any() const
|
EIGEN_DEVICE_FUNC inline bool DenseBase<Derived>::any() const
|
||||||
{
|
{
|
||||||
typedef internal::evaluator<Derived> Evaluator;
|
typedef internal::evaluator<Derived> Evaluator;
|
||||||
enum {
|
enum {
|
||||||
unroll = SizeAtCompileTime != Dynamic
|
unroll = SizeAtCompileTime != Dynamic
|
||||||
&& SizeAtCompileTime * (Evaluator::CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
|
&& SizeAtCompileTime * (int(Evaluator::CoeffReadCost) + int(NumTraits<Scalar>::AddCost)) <= EIGEN_UNROLLING_LIMIT
|
||||||
};
|
};
|
||||||
Evaluator evaluator(derived());
|
Evaluator evaluator(derived());
|
||||||
if(unroll)
|
if(unroll)
|
||||||
return internal::any_unroller<Evaluator, unroll ? int(SizeAtCompileTime) : Dynamic>::run(evaluator);
|
return internal::any_unroller<Evaluator, unroll ? int(SizeAtCompileTime) : Dynamic, internal::traits<Derived>::RowsAtCompileTime>::run(evaluator);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(Index j = 0; j < cols(); ++j)
|
for(Index j = 0; j < cols(); ++j)
|
||||||
|
|
@ -126,7 +124,7 @@ inline bool DenseBase<Derived>::any() const
|
||||||
* \sa all(), any()
|
* \sa all(), any()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline Eigen::Index DenseBase<Derived>::count() const
|
EIGEN_DEVICE_FUNC inline Eigen::Index DenseBase<Derived>::count() const
|
||||||
{
|
{
|
||||||
return derived().template cast<bool>().template cast<Index>().sum();
|
return derived().template cast<bool>().template cast<Index>().sum();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,8 @@ struct CommaInitializer
|
||||||
inline CommaInitializer(XprType& xpr, const Scalar& s)
|
inline CommaInitializer(XprType& xpr, const Scalar& s)
|
||||||
: m_xpr(xpr), m_row(0), m_col(1), m_currentBlockRows(1)
|
: m_xpr(xpr), m_row(0), m_col(1), m_currentBlockRows(1)
|
||||||
{
|
{
|
||||||
|
eigen_assert(m_xpr.rows() > 0 && m_xpr.cols() > 0
|
||||||
|
&& "Cannot comma-initialize a 0x0 matrix (operator<<)");
|
||||||
m_xpr.coeffRef(0,0) = s;
|
m_xpr.coeffRef(0,0) = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -41,6 +43,8 @@ struct CommaInitializer
|
||||||
inline CommaInitializer(XprType& xpr, const DenseBase<OtherDerived>& other)
|
inline CommaInitializer(XprType& xpr, const DenseBase<OtherDerived>& other)
|
||||||
: m_xpr(xpr), m_row(0), m_col(other.cols()), m_currentBlockRows(other.rows())
|
: m_xpr(xpr), m_row(0), m_col(other.cols()), m_currentBlockRows(other.rows())
|
||||||
{
|
{
|
||||||
|
eigen_assert(m_xpr.rows() >= other.rows() && m_xpr.cols() >= other.cols()
|
||||||
|
&& "Cannot comma-initialize a 0x0 matrix (operator<<)");
|
||||||
m_xpr.block(0, 0, other.rows(), other.cols()) = other;
|
m_xpr.block(0, 0, other.rows(), other.cols()) = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -141,7 +145,7 @@ struct CommaInitializer
|
||||||
* \sa CommaInitializer::finished(), class CommaInitializer
|
* \sa CommaInitializer::finished(), class CommaInitializer
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline CommaInitializer<Derived> DenseBase<Derived>::operator<< (const Scalar& s)
|
EIGEN_DEVICE_FUNC 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);
|
||||||
}
|
}
|
||||||
|
|
@ -149,7 +153,7 @@ inline CommaInitializer<Derived> DenseBase<Derived>::operator<< (const Scalar& s
|
||||||
/** \sa operator<<(const Scalar&) */
|
/** \sa operator<<(const Scalar&) */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
inline CommaInitializer<Derived>
|
EIGEN_DEVICE_FUNC inline CommaInitializer<Derived>
|
||||||
DenseBase<Derived>::operator<<(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);
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,8 @@ template<typename T>
|
||||||
struct evaluator : public unary_evaluator<T>
|
struct evaluator : public unary_evaluator<T>
|
||||||
{
|
{
|
||||||
typedef unary_evaluator<T> Base;
|
typedef unary_evaluator<T> Base;
|
||||||
EIGEN_DEVICE_FUNC explicit evaluator(const T& xpr) : Base(xpr) {}
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
explicit evaluator(const T& xpr) : Base(xpr) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -99,14 +100,14 @@ template<typename T>
|
||||||
struct evaluator<const T>
|
struct evaluator<const T>
|
||||||
: evaluator<T>
|
: evaluator<T>
|
||||||
{
|
{
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
explicit evaluator(const T& xpr) : evaluator<T>(xpr) {}
|
explicit evaluator(const T& xpr) : evaluator<T>(xpr) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------- base class for all evaluators ----------
|
// ---------- base class for all evaluators ----------
|
||||||
|
|
||||||
template<typename ExpressionType>
|
template<typename ExpressionType>
|
||||||
struct evaluator_base : public noncopyable
|
struct evaluator_base
|
||||||
{
|
{
|
||||||
// TODO that's not very nice to have to propagate all these traits. They are currently only needed to handle outer,inner indices.
|
// TODO that's not very nice to have to propagate all these traits. They are currently only needed to handle outer,inner indices.
|
||||||
typedef traits<ExpressionType> ExpressionTraits;
|
typedef traits<ExpressionType> ExpressionTraits;
|
||||||
|
|
@ -114,6 +115,14 @@ struct evaluator_base : public noncopyable
|
||||||
enum {
|
enum {
|
||||||
Alignment = 0
|
Alignment = 0
|
||||||
};
|
};
|
||||||
|
// noncopyable:
|
||||||
|
// Don't make this class inherit noncopyable as this kills EBO (Empty Base Optimization)
|
||||||
|
// and make complex evaluator much larger than then should do.
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE evaluator_base() {}
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ~evaluator_base() {}
|
||||||
|
private:
|
||||||
|
EIGEN_DEVICE_FUNC evaluator_base(const evaluator_base&);
|
||||||
|
EIGEN_DEVICE_FUNC const evaluator_base& operator=(const evaluator_base&);
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------- Matrix and Array --------------------
|
// -------------------- Matrix and Array --------------------
|
||||||
|
|
@ -123,6 +132,33 @@ struct evaluator_base : public noncopyable
|
||||||
// Here we directly specialize evaluator. This is not really a unary expression, and it is, by definition, dense,
|
// Here we directly specialize evaluator. This is not really a unary expression, and it is, by definition, dense,
|
||||||
// so no need for more sophisticated dispatching.
|
// so no need for more sophisticated dispatching.
|
||||||
|
|
||||||
|
// this helper permits to completely eliminate m_outerStride if it is known at compiletime.
|
||||||
|
template<typename Scalar,int OuterStride> class plainobjectbase_evaluator_data {
|
||||||
|
public:
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
plainobjectbase_evaluator_data(const Scalar* ptr, Index outerStride) : data(ptr)
|
||||||
|
{
|
||||||
|
#ifndef EIGEN_INTERNAL_DEBUGGING
|
||||||
|
EIGEN_UNUSED_VARIABLE(outerStride);
|
||||||
|
#endif
|
||||||
|
eigen_internal_assert(outerStride==OuterStride);
|
||||||
|
}
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
|
Index outerStride() const EIGEN_NOEXCEPT { return OuterStride; }
|
||||||
|
const Scalar *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Scalar> class plainobjectbase_evaluator_data<Scalar,Dynamic> {
|
||||||
|
public:
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
plainobjectbase_evaluator_data(const Scalar* ptr, Index outerStride) : data(ptr), m_outerStride(outerStride) {}
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
Index outerStride() const { return m_outerStride; }
|
||||||
|
const Scalar *data;
|
||||||
|
protected:
|
||||||
|
Index m_outerStride;
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
struct evaluator<PlainObjectBase<Derived> >
|
struct evaluator<PlainObjectBase<Derived> >
|
||||||
: evaluator_base<Derived>
|
: evaluator_base<Derived>
|
||||||
|
|
@ -141,18 +177,23 @@ struct evaluator<PlainObjectBase<Derived> >
|
||||||
Flags = traits<Derived>::EvaluatorFlags,
|
Flags = traits<Derived>::EvaluatorFlags,
|
||||||
Alignment = traits<Derived>::Alignment
|
Alignment = traits<Derived>::Alignment
|
||||||
};
|
};
|
||||||
|
enum {
|
||||||
EIGEN_DEVICE_FUNC evaluator()
|
// We do not need to know the outer stride for vectors
|
||||||
: m_data(0),
|
OuterStrideAtCompileTime = IsVectorAtCompileTime ? 0
|
||||||
m_outerStride(IsVectorAtCompileTime ? 0
|
|
||||||
: int(IsRowMajor) ? ColsAtCompileTime
|
: int(IsRowMajor) ? ColsAtCompileTime
|
||||||
: RowsAtCompileTime)
|
: RowsAtCompileTime
|
||||||
|
};
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
evaluator()
|
||||||
|
: m_d(0,OuterStrideAtCompileTime)
|
||||||
{
|
{
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit evaluator(const PlainObjectType& m)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
: m_data(m.data()), m_outerStride(IsVectorAtCompileTime ? 0 : m.outerStride())
|
explicit evaluator(const PlainObjectType& m)
|
||||||
|
: m_d(m.data(),IsVectorAtCompileTime ? 0 : m.outerStride())
|
||||||
{
|
{
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
||||||
}
|
}
|
||||||
|
|
@ -161,30 +202,30 @@ struct evaluator<PlainObjectBase<Derived> >
|
||||||
CoeffReturnType coeff(Index row, Index col) const
|
CoeffReturnType coeff(Index row, Index col) const
|
||||||
{
|
{
|
||||||
if (IsRowMajor)
|
if (IsRowMajor)
|
||||||
return m_data[row * m_outerStride.value() + col];
|
return m_d.data[row * m_d.outerStride() + col];
|
||||||
else
|
else
|
||||||
return m_data[row + col * m_outerStride.value()];
|
return m_d.data[row + col * m_d.outerStride()];
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
CoeffReturnType coeff(Index index) const
|
CoeffReturnType coeff(Index index) const
|
||||||
{
|
{
|
||||||
return m_data[index];
|
return m_d.data[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
Scalar& coeffRef(Index row, Index col)
|
Scalar& coeffRef(Index row, Index col)
|
||||||
{
|
{
|
||||||
if (IsRowMajor)
|
if (IsRowMajor)
|
||||||
return const_cast<Scalar*>(m_data)[row * m_outerStride.value() + col];
|
return const_cast<Scalar*>(m_d.data)[row * m_d.outerStride() + col];
|
||||||
else
|
else
|
||||||
return const_cast<Scalar*>(m_data)[row + col * m_outerStride.value()];
|
return const_cast<Scalar*>(m_d.data)[row + col * m_d.outerStride()];
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
Scalar& coeffRef(Index index)
|
Scalar& coeffRef(Index index)
|
||||||
{
|
{
|
||||||
return const_cast<Scalar*>(m_data)[index];
|
return const_cast<Scalar*>(m_d.data)[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
template<int LoadMode, typename PacketType>
|
||||||
|
|
@ -192,16 +233,16 @@ struct evaluator<PlainObjectBase<Derived> >
|
||||||
PacketType packet(Index row, Index col) const
|
PacketType packet(Index row, Index col) const
|
||||||
{
|
{
|
||||||
if (IsRowMajor)
|
if (IsRowMajor)
|
||||||
return ploadt<PacketType, LoadMode>(m_data + row * m_outerStride.value() + col);
|
return ploadt<PacketType, LoadMode>(m_d.data + row * m_d.outerStride() + col);
|
||||||
else
|
else
|
||||||
return ploadt<PacketType, LoadMode>(m_data + row + col * m_outerStride.value());
|
return ploadt<PacketType, LoadMode>(m_d.data + row + col * m_d.outerStride());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
template<int LoadMode, typename PacketType>
|
||||||
EIGEN_STRONG_INLINE
|
EIGEN_STRONG_INLINE
|
||||||
PacketType packet(Index index) const
|
PacketType packet(Index index) const
|
||||||
{
|
{
|
||||||
return ploadt<PacketType, LoadMode>(m_data + index);
|
return ploadt<PacketType, LoadMode>(m_d.data + index);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int StoreMode,typename PacketType>
|
template<int StoreMode,typename PacketType>
|
||||||
|
|
@ -210,26 +251,22 @@ struct evaluator<PlainObjectBase<Derived> >
|
||||||
{
|
{
|
||||||
if (IsRowMajor)
|
if (IsRowMajor)
|
||||||
return pstoret<Scalar, PacketType, StoreMode>
|
return pstoret<Scalar, PacketType, StoreMode>
|
||||||
(const_cast<Scalar*>(m_data) + row * m_outerStride.value() + col, x);
|
(const_cast<Scalar*>(m_d.data) + row * m_d.outerStride() + col, x);
|
||||||
else
|
else
|
||||||
return pstoret<Scalar, PacketType, StoreMode>
|
return pstoret<Scalar, PacketType, StoreMode>
|
||||||
(const_cast<Scalar*>(m_data) + row + col * m_outerStride.value(), x);
|
(const_cast<Scalar*>(m_d.data) + row + col * m_d.outerStride(), x);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int StoreMode, typename PacketType>
|
template<int StoreMode, typename PacketType>
|
||||||
EIGEN_STRONG_INLINE
|
EIGEN_STRONG_INLINE
|
||||||
void writePacket(Index index, const PacketType& x)
|
void writePacket(Index index, const PacketType& x)
|
||||||
{
|
{
|
||||||
return pstoret<Scalar, PacketType, StoreMode>(const_cast<Scalar*>(m_data) + index, x);
|
return pstoret<Scalar, PacketType, StoreMode>(const_cast<Scalar*>(m_d.data) + index, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const Scalar *m_data;
|
|
||||||
|
|
||||||
// We do not need to know the outer stride for vectors
|
plainobjectbase_evaluator_data<Scalar,OuterStrideAtCompileTime> m_d;
|
||||||
variable_if_dynamic<Index, IsVectorAtCompileTime ? 0
|
|
||||||
: int(IsRowMajor) ? ColsAtCompileTime
|
|
||||||
: RowsAtCompileTime> m_outerStride;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
|
template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
|
||||||
|
|
@ -238,9 +275,11 @@ struct evaluator<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
|
||||||
{
|
{
|
||||||
typedef Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> XprType;
|
typedef Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> XprType;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC evaluator() {}
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
evaluator() {}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit evaluator(const XprType& m)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
explicit evaluator(const XprType& m)
|
||||||
: evaluator<PlainObjectBase<XprType> >(m)
|
: evaluator<PlainObjectBase<XprType> >(m)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
@ -251,9 +290,11 @@ struct evaluator<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
|
||||||
{
|
{
|
||||||
typedef Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> XprType;
|
typedef Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> XprType;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC evaluator() {}
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
evaluator() {}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit evaluator(const XprType& m)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
explicit evaluator(const XprType& m)
|
||||||
: evaluator<PlainObjectBase<XprType> >(m)
|
: evaluator<PlainObjectBase<XprType> >(m)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
@ -272,7 +313,8 @@ struct unary_evaluator<Transpose<ArgType>, IndexBased>
|
||||||
Alignment = evaluator<ArgType>::Alignment
|
Alignment = evaluator<ArgType>::Alignment
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& t) : m_argImpl(t.nestedExpression()) {}
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
explicit unary_evaluator(const XprType& t) : m_argImpl(t.nestedExpression()) {}
|
||||||
|
|
||||||
typedef typename XprType::Scalar Scalar;
|
typedef typename XprType::Scalar Scalar;
|
||||||
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
||||||
|
|
@ -519,7 +561,7 @@ struct unary_evaluator<CwiseUnaryOp<UnaryOp, ArgType>, IndexBased >
|
||||||
typedef CwiseUnaryOp<UnaryOp, ArgType> XprType;
|
typedef CwiseUnaryOp<UnaryOp, ArgType> XprType;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CoeffReadCost = evaluator<ArgType>::CoeffReadCost + functor_traits<UnaryOp>::Cost,
|
CoeffReadCost = int(evaluator<ArgType>::CoeffReadCost) + int(functor_traits<UnaryOp>::Cost),
|
||||||
|
|
||||||
Flags = evaluator<ArgType>::Flags
|
Flags = evaluator<ArgType>::Flags
|
||||||
& (HereditaryBits | LinearAccessBit | (functor_traits<UnaryOp>::PacketAccess ? PacketAccessBit : 0)),
|
& (HereditaryBits | LinearAccessBit | (functor_traits<UnaryOp>::PacketAccess ? PacketAccessBit : 0)),
|
||||||
|
|
@ -527,9 +569,7 @@ struct unary_evaluator<CwiseUnaryOp<UnaryOp, ArgType>, IndexBased >
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
explicit unary_evaluator(const XprType& op)
|
explicit unary_evaluator(const XprType& op) : m_d(op)
|
||||||
: m_functor(op.functor()),
|
|
||||||
m_argImpl(op.nestedExpression())
|
|
||||||
{
|
{
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<UnaryOp>::Cost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<UnaryOp>::Cost);
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
||||||
|
|
@ -540,32 +580,43 @@ struct unary_evaluator<CwiseUnaryOp<UnaryOp, ArgType>, IndexBased >
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
CoeffReturnType coeff(Index row, Index col) const
|
CoeffReturnType coeff(Index row, Index col) const
|
||||||
{
|
{
|
||||||
return m_functor(m_argImpl.coeff(row, col));
|
return m_d.func()(m_d.argImpl.coeff(row, col));
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
CoeffReturnType coeff(Index index) const
|
CoeffReturnType coeff(Index index) const
|
||||||
{
|
{
|
||||||
return m_functor(m_argImpl.coeff(index));
|
return m_d.func()(m_d.argImpl.coeff(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
template<int LoadMode, typename PacketType>
|
||||||
EIGEN_STRONG_INLINE
|
EIGEN_STRONG_INLINE
|
||||||
PacketType packet(Index row, Index col) const
|
PacketType packet(Index row, Index col) const
|
||||||
{
|
{
|
||||||
return m_functor.packetOp(m_argImpl.template packet<LoadMode, PacketType>(row, col));
|
return m_d.func().packetOp(m_d.argImpl.template packet<LoadMode, PacketType>(row, col));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
template<int LoadMode, typename PacketType>
|
||||||
EIGEN_STRONG_INLINE
|
EIGEN_STRONG_INLINE
|
||||||
PacketType packet(Index index) const
|
PacketType packet(Index index) const
|
||||||
{
|
{
|
||||||
return m_functor.packetOp(m_argImpl.template packet<LoadMode, PacketType>(index));
|
return m_d.func().packetOp(m_d.argImpl.template packet<LoadMode, PacketType>(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const UnaryOp m_functor;
|
|
||||||
evaluator<ArgType> m_argImpl;
|
// this helper permits to completely eliminate the functor if it is empty
|
||||||
|
struct Data
|
||||||
|
{
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
Data(const XprType& xpr) : op(xpr.functor()), argImpl(xpr.nestedExpression()) {}
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
const UnaryOp& func() const { return op; }
|
||||||
|
UnaryOp op;
|
||||||
|
evaluator<ArgType> argImpl;
|
||||||
|
};
|
||||||
|
|
||||||
|
Data m_d;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------- CwiseTernaryOp --------------------
|
// -------------------- CwiseTernaryOp --------------------
|
||||||
|
|
@ -588,7 +639,7 @@ struct ternary_evaluator<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>, IndexBased
|
||||||
typedef CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> XprType;
|
typedef CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> XprType;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CoeffReadCost = evaluator<Arg1>::CoeffReadCost + evaluator<Arg2>::CoeffReadCost + evaluator<Arg3>::CoeffReadCost + functor_traits<TernaryOp>::Cost,
|
CoeffReadCost = int(evaluator<Arg1>::CoeffReadCost) + int(evaluator<Arg2>::CoeffReadCost) + int(evaluator<Arg3>::CoeffReadCost) + int(functor_traits<TernaryOp>::Cost),
|
||||||
|
|
||||||
Arg1Flags = evaluator<Arg1>::Flags,
|
Arg1Flags = evaluator<Arg1>::Flags,
|
||||||
Arg2Flags = evaluator<Arg2>::Flags,
|
Arg2Flags = evaluator<Arg2>::Flags,
|
||||||
|
|
@ -609,11 +660,7 @@ struct ternary_evaluator<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>, IndexBased
|
||||||
evaluator<Arg3>::Alignment)
|
evaluator<Arg3>::Alignment)
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit ternary_evaluator(const XprType& xpr)
|
EIGEN_DEVICE_FUNC explicit ternary_evaluator(const XprType& xpr) : m_d(xpr)
|
||||||
: m_functor(xpr.functor()),
|
|
||||||
m_arg1Impl(xpr.arg1()),
|
|
||||||
m_arg2Impl(xpr.arg2()),
|
|
||||||
m_arg3Impl(xpr.arg3())
|
|
||||||
{
|
{
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<TernaryOp>::Cost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<TernaryOp>::Cost);
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
||||||
|
|
@ -624,38 +671,48 @@ struct ternary_evaluator<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>, IndexBased
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
CoeffReturnType coeff(Index row, Index col) const
|
CoeffReturnType coeff(Index row, Index col) const
|
||||||
{
|
{
|
||||||
return m_functor(m_arg1Impl.coeff(row, col), m_arg2Impl.coeff(row, col), m_arg3Impl.coeff(row, col));
|
return m_d.func()(m_d.arg1Impl.coeff(row, col), m_d.arg2Impl.coeff(row, col), m_d.arg3Impl.coeff(row, col));
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
CoeffReturnType coeff(Index index) const
|
CoeffReturnType coeff(Index index) const
|
||||||
{
|
{
|
||||||
return m_functor(m_arg1Impl.coeff(index), m_arg2Impl.coeff(index), m_arg3Impl.coeff(index));
|
return m_d.func()(m_d.arg1Impl.coeff(index), m_d.arg2Impl.coeff(index), m_d.arg3Impl.coeff(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
template<int LoadMode, typename PacketType>
|
||||||
EIGEN_STRONG_INLINE
|
EIGEN_STRONG_INLINE
|
||||||
PacketType packet(Index row, Index col) const
|
PacketType packet(Index row, Index col) const
|
||||||
{
|
{
|
||||||
return m_functor.packetOp(m_arg1Impl.template packet<LoadMode,PacketType>(row, col),
|
return m_d.func().packetOp(m_d.arg1Impl.template packet<LoadMode,PacketType>(row, col),
|
||||||
m_arg2Impl.template packet<LoadMode,PacketType>(row, col),
|
m_d.arg2Impl.template packet<LoadMode,PacketType>(row, col),
|
||||||
m_arg3Impl.template packet<LoadMode,PacketType>(row, col));
|
m_d.arg3Impl.template packet<LoadMode,PacketType>(row, col));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
template<int LoadMode, typename PacketType>
|
||||||
EIGEN_STRONG_INLINE
|
EIGEN_STRONG_INLINE
|
||||||
PacketType packet(Index index) const
|
PacketType packet(Index index) const
|
||||||
{
|
{
|
||||||
return m_functor.packetOp(m_arg1Impl.template packet<LoadMode,PacketType>(index),
|
return m_d.func().packetOp(m_d.arg1Impl.template packet<LoadMode,PacketType>(index),
|
||||||
m_arg2Impl.template packet<LoadMode,PacketType>(index),
|
m_d.arg2Impl.template packet<LoadMode,PacketType>(index),
|
||||||
m_arg3Impl.template packet<LoadMode,PacketType>(index));
|
m_d.arg3Impl.template packet<LoadMode,PacketType>(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const TernaryOp m_functor;
|
// this helper permits to completely eliminate the functor if it is empty
|
||||||
evaluator<Arg1> m_arg1Impl;
|
struct Data
|
||||||
evaluator<Arg2> m_arg2Impl;
|
{
|
||||||
evaluator<Arg3> m_arg3Impl;
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
Data(const XprType& xpr) : op(xpr.functor()), arg1Impl(xpr.arg1()), arg2Impl(xpr.arg2()), arg3Impl(xpr.arg3()) {}
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
const TernaryOp& func() const { return op; }
|
||||||
|
TernaryOp op;
|
||||||
|
evaluator<Arg1> arg1Impl;
|
||||||
|
evaluator<Arg2> arg2Impl;
|
||||||
|
evaluator<Arg3> arg3Impl;
|
||||||
|
};
|
||||||
|
|
||||||
|
Data m_d;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------- CwiseBinaryOp --------------------
|
// -------------------- CwiseBinaryOp --------------------
|
||||||
|
|
@ -668,7 +725,8 @@ struct evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
|
||||||
typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
|
typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
|
||||||
typedef binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > Base;
|
typedef binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > Base;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr) : Base(xpr) {}
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
explicit evaluator(const XprType& xpr) : Base(xpr) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BinaryOp, typename Lhs, typename Rhs>
|
template<typename BinaryOp, typename Lhs, typename Rhs>
|
||||||
|
|
@ -678,7 +736,7 @@ struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>, IndexBased, IndexBase
|
||||||
typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
|
typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CoeffReadCost = evaluator<Lhs>::CoeffReadCost + evaluator<Rhs>::CoeffReadCost + functor_traits<BinaryOp>::Cost,
|
CoeffReadCost = int(evaluator<Lhs>::CoeffReadCost) + int(evaluator<Rhs>::CoeffReadCost) + int(functor_traits<BinaryOp>::Cost),
|
||||||
|
|
||||||
LhsFlags = evaluator<Lhs>::Flags,
|
LhsFlags = evaluator<Lhs>::Flags,
|
||||||
RhsFlags = evaluator<Rhs>::Flags,
|
RhsFlags = evaluator<Rhs>::Flags,
|
||||||
|
|
@ -696,10 +754,8 @@ struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>, IndexBased, IndexBase
|
||||||
Alignment = EIGEN_PLAIN_ENUM_MIN(evaluator<Lhs>::Alignment,evaluator<Rhs>::Alignment)
|
Alignment = EIGEN_PLAIN_ENUM_MIN(evaluator<Lhs>::Alignment,evaluator<Rhs>::Alignment)
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit binary_evaluator(const XprType& xpr)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
: m_functor(xpr.functor()),
|
explicit binary_evaluator(const XprType& xpr) : m_d(xpr)
|
||||||
m_lhsImpl(xpr.lhs()),
|
|
||||||
m_rhsImpl(xpr.rhs())
|
|
||||||
{
|
{
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
||||||
|
|
@ -710,35 +766,46 @@ struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>, IndexBased, IndexBase
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
CoeffReturnType coeff(Index row, Index col) const
|
CoeffReturnType coeff(Index row, Index col) const
|
||||||
{
|
{
|
||||||
return m_functor(m_lhsImpl.coeff(row, col), m_rhsImpl.coeff(row, col));
|
return m_d.func()(m_d.lhsImpl.coeff(row, col), m_d.rhsImpl.coeff(row, col));
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
CoeffReturnType coeff(Index index) const
|
CoeffReturnType coeff(Index index) const
|
||||||
{
|
{
|
||||||
return m_functor(m_lhsImpl.coeff(index), m_rhsImpl.coeff(index));
|
return m_d.func()(m_d.lhsImpl.coeff(index), m_d.rhsImpl.coeff(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
template<int LoadMode, typename PacketType>
|
||||||
EIGEN_STRONG_INLINE
|
EIGEN_STRONG_INLINE
|
||||||
PacketType packet(Index row, Index col) const
|
PacketType packet(Index row, Index col) const
|
||||||
{
|
{
|
||||||
return m_functor.packetOp(m_lhsImpl.template packet<LoadMode,PacketType>(row, col),
|
return m_d.func().packetOp(m_d.lhsImpl.template packet<LoadMode,PacketType>(row, col),
|
||||||
m_rhsImpl.template packet<LoadMode,PacketType>(row, col));
|
m_d.rhsImpl.template packet<LoadMode,PacketType>(row, col));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
template<int LoadMode, typename PacketType>
|
||||||
EIGEN_STRONG_INLINE
|
EIGEN_STRONG_INLINE
|
||||||
PacketType packet(Index index) const
|
PacketType packet(Index index) const
|
||||||
{
|
{
|
||||||
return m_functor.packetOp(m_lhsImpl.template packet<LoadMode,PacketType>(index),
|
return m_d.func().packetOp(m_d.lhsImpl.template packet<LoadMode,PacketType>(index),
|
||||||
m_rhsImpl.template packet<LoadMode,PacketType>(index));
|
m_d.rhsImpl.template packet<LoadMode,PacketType>(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const BinaryOp m_functor;
|
|
||||||
evaluator<Lhs> m_lhsImpl;
|
// this helper permits to completely eliminate the functor if it is empty
|
||||||
evaluator<Rhs> m_rhsImpl;
|
struct Data
|
||||||
|
{
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
Data(const XprType& xpr) : op(xpr.functor()), lhsImpl(xpr.lhs()), rhsImpl(xpr.rhs()) {}
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
const BinaryOp& func() const { return op; }
|
||||||
|
BinaryOp op;
|
||||||
|
evaluator<Lhs> lhsImpl;
|
||||||
|
evaluator<Rhs> rhsImpl;
|
||||||
|
};
|
||||||
|
|
||||||
|
Data m_d;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------- CwiseUnaryView --------------------
|
// -------------------- CwiseUnaryView --------------------
|
||||||
|
|
@ -750,16 +817,14 @@ struct unary_evaluator<CwiseUnaryView<UnaryOp, ArgType>, IndexBased>
|
||||||
typedef CwiseUnaryView<UnaryOp, ArgType> XprType;
|
typedef CwiseUnaryView<UnaryOp, ArgType> XprType;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CoeffReadCost = evaluator<ArgType>::CoeffReadCost + functor_traits<UnaryOp>::Cost,
|
CoeffReadCost = int(evaluator<ArgType>::CoeffReadCost) + int(functor_traits<UnaryOp>::Cost),
|
||||||
|
|
||||||
Flags = (evaluator<ArgType>::Flags & (HereditaryBits | LinearAccessBit | DirectAccessBit)),
|
Flags = (evaluator<ArgType>::Flags & (HereditaryBits | LinearAccessBit | DirectAccessBit)),
|
||||||
|
|
||||||
Alignment = 0 // FIXME it is not very clear why alignment is necessarily lost...
|
Alignment = 0 // FIXME it is not very clear why alignment is necessarily lost...
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& op)
|
EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& op) : m_d(op)
|
||||||
: m_unaryOp(op.functor()),
|
|
||||||
m_argImpl(op.nestedExpression())
|
|
||||||
{
|
{
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<UnaryOp>::Cost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<UnaryOp>::Cost);
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
||||||
|
|
@ -771,30 +836,41 @@ struct unary_evaluator<CwiseUnaryView<UnaryOp, ArgType>, IndexBased>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
CoeffReturnType coeff(Index row, Index col) const
|
CoeffReturnType coeff(Index row, Index col) const
|
||||||
{
|
{
|
||||||
return m_unaryOp(m_argImpl.coeff(row, col));
|
return m_d.func()(m_d.argImpl.coeff(row, col));
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
CoeffReturnType coeff(Index index) const
|
CoeffReturnType coeff(Index index) const
|
||||||
{
|
{
|
||||||
return m_unaryOp(m_argImpl.coeff(index));
|
return m_d.func()(m_d.argImpl.coeff(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
Scalar& coeffRef(Index row, Index col)
|
Scalar& coeffRef(Index row, Index col)
|
||||||
{
|
{
|
||||||
return m_unaryOp(m_argImpl.coeffRef(row, col));
|
return m_d.func()(m_d.argImpl.coeffRef(row, col));
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
Scalar& coeffRef(Index index)
|
Scalar& coeffRef(Index index)
|
||||||
{
|
{
|
||||||
return m_unaryOp(m_argImpl.coeffRef(index));
|
return m_d.func()(m_d.argImpl.coeffRef(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const UnaryOp m_unaryOp;
|
|
||||||
evaluator<ArgType> m_argImpl;
|
// this helper permits to completely eliminate the functor if it is empty
|
||||||
|
struct Data
|
||||||
|
{
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
Data(const XprType& xpr) : op(xpr.functor()), argImpl(xpr.nestedExpression()) {}
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
const UnaryOp& func() const { return op; }
|
||||||
|
UnaryOp op;
|
||||||
|
evaluator<ArgType> argImpl;
|
||||||
|
};
|
||||||
|
|
||||||
|
Data m_d;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------- Map --------------------
|
// -------------------- Map --------------------
|
||||||
|
|
@ -818,7 +894,8 @@ struct mapbase_evaluator : evaluator_base<Derived>
|
||||||
CoeffReadCost = NumTraits<Scalar>::ReadCost
|
CoeffReadCost = NumTraits<Scalar>::ReadCost
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit mapbase_evaluator(const XprType& map)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
explicit mapbase_evaluator(const XprType& map)
|
||||||
: m_data(const_cast<PointerType>(map.data())),
|
: m_data(const_cast<PointerType>(map.data())),
|
||||||
m_innerStride(map.innerStride()),
|
m_innerStride(map.innerStride()),
|
||||||
m_outerStride(map.outerStride())
|
m_outerStride(map.outerStride())
|
||||||
|
|
@ -882,10 +959,14 @@ struct mapbase_evaluator : evaluator_base<Derived>
|
||||||
internal::pstoret<Scalar, PacketType, StoreMode>(m_data + index * m_innerStride.value(), x);
|
internal::pstoret<Scalar, PacketType, StoreMode>(m_data + index * m_innerStride.value(), x);
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
inline Index rowStride() const { return XprType::IsRowMajor ? m_outerStride.value() : m_innerStride.value(); }
|
Index rowStride() const EIGEN_NOEXCEPT {
|
||||||
EIGEN_DEVICE_FUNC
|
return XprType::IsRowMajor ? m_outerStride.value() : m_innerStride.value();
|
||||||
inline Index colStride() const { return XprType::IsRowMajor ? m_innerStride.value() : m_outerStride.value(); }
|
}
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
|
Index colStride() const EIGEN_NOEXCEPT {
|
||||||
|
return XprType::IsRowMajor ? m_innerStride.value() : m_outerStride.value();
|
||||||
|
}
|
||||||
|
|
||||||
PointerType m_data;
|
PointerType m_data;
|
||||||
const internal::variable_if_dynamic<Index, XprType::InnerStrideAtCompileTime> m_innerStride;
|
const internal::variable_if_dynamic<Index, XprType::InnerStrideAtCompileTime> m_innerStride;
|
||||||
|
|
@ -938,7 +1019,8 @@ struct evaluator<Ref<PlainObjectType, RefOptions, StrideType> >
|
||||||
Alignment = evaluator<Map<PlainObjectType, RefOptions, StrideType> >::Alignment
|
Alignment = evaluator<Map<PlainObjectType, RefOptions, StrideType> >::Alignment
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit evaluator(const XprType& ref)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
explicit evaluator(const XprType& ref)
|
||||||
: mapbase_evaluator<XprType, PlainObjectType>(ref)
|
: mapbase_evaluator<XprType, PlainObjectType>(ref)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
@ -993,7 +1075,8 @@ struct evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel> >
|
||||||
Alignment = EIGEN_PLAIN_ENUM_MIN(evaluator<ArgType>::Alignment, Alignment0)
|
Alignment = EIGEN_PLAIN_ENUM_MIN(evaluator<ArgType>::Alignment, Alignment0)
|
||||||
};
|
};
|
||||||
typedef block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel> block_evaluator_type;
|
typedef block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel> block_evaluator_type;
|
||||||
EIGEN_DEVICE_FUNC explicit evaluator(const XprType& block) : block_evaluator_type(block)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
explicit evaluator(const XprType& block) : block_evaluator_type(block)
|
||||||
{
|
{
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
||||||
}
|
}
|
||||||
|
|
@ -1006,7 +1089,8 @@ struct block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel, /*HasDirectAcc
|
||||||
{
|
{
|
||||||
typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
|
typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit block_evaluator(const XprType& block)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
explicit block_evaluator(const XprType& block)
|
||||||
: unary_evaluator<XprType>(block)
|
: unary_evaluator<XprType>(block)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
@ -1017,11 +1101,12 @@ struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IndexBa
|
||||||
{
|
{
|
||||||
typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
|
typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& block)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
explicit unary_evaluator(const XprType& block)
|
||||||
: m_argImpl(block.nestedExpression()),
|
: m_argImpl(block.nestedExpression()),
|
||||||
m_startRow(block.startRow()),
|
m_startRow(block.startRow()),
|
||||||
m_startCol(block.startCol()),
|
m_startCol(block.startCol()),
|
||||||
m_linear_offset(InnerPanel?(XprType::IsRowMajor ? block.startRow()*block.cols() : block.startCol()*block.rows()):0)
|
m_linear_offset(ForwardLinearAccess?(ArgType::IsRowMajor ? block.startRow()*block.nestedExpression().cols() + block.startCol() : block.startCol()*block.nestedExpression().rows() + block.startRow()):0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
typedef typename XprType::Scalar Scalar;
|
typedef typename XprType::Scalar Scalar;
|
||||||
|
|
@ -1029,7 +1114,7 @@ struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IndexBa
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
RowsAtCompileTime = XprType::RowsAtCompileTime,
|
RowsAtCompileTime = XprType::RowsAtCompileTime,
|
||||||
ForwardLinearAccess = InnerPanel && bool(evaluator<ArgType>::Flags&LinearAccessBit)
|
ForwardLinearAccess = (InnerPanel || int(XprType::IsRowMajor)==int(ArgType::IsRowMajor)) && bool(evaluator<ArgType>::Flags&LinearAccessBit)
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
|
@ -1041,10 +1126,7 @@ struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IndexBa
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
CoeffReturnType coeff(Index index) const
|
CoeffReturnType coeff(Index index) const
|
||||||
{
|
{
|
||||||
if (ForwardLinearAccess)
|
return linear_coeff_impl(index, bool_constant<ForwardLinearAccess>());
|
||||||
return m_argImpl.coeff(m_linear_offset.value() + index);
|
|
||||||
else
|
|
||||||
return coeff(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
|
@ -1056,10 +1138,7 @@ struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IndexBa
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
Scalar& coeffRef(Index index)
|
Scalar& coeffRef(Index index)
|
||||||
{
|
{
|
||||||
if (ForwardLinearAccess)
|
return linear_coeffRef_impl(index, bool_constant<ForwardLinearAccess>());
|
||||||
return m_argImpl.coeffRef(m_linear_offset.value() + index);
|
|
||||||
else
|
|
||||||
return coeffRef(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
template<int LoadMode, typename PacketType>
|
||||||
|
|
@ -1100,10 +1179,32 @@ struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IndexBa
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
CoeffReturnType linear_coeff_impl(Index index, internal::true_type /* ForwardLinearAccess */) const
|
||||||
|
{
|
||||||
|
return m_argImpl.coeff(m_linear_offset.value() + index);
|
||||||
|
}
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
CoeffReturnType linear_coeff_impl(Index index, internal::false_type /* not ForwardLinearAccess */) const
|
||||||
|
{
|
||||||
|
return coeff(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
Scalar& linear_coeffRef_impl(Index index, internal::true_type /* ForwardLinearAccess */)
|
||||||
|
{
|
||||||
|
return m_argImpl.coeffRef(m_linear_offset.value() + index);
|
||||||
|
}
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
Scalar& linear_coeffRef_impl(Index index, internal::false_type /* not ForwardLinearAccess */)
|
||||||
|
{
|
||||||
|
return coeffRef(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0);
|
||||||
|
}
|
||||||
|
|
||||||
evaluator<ArgType> m_argImpl;
|
evaluator<ArgType> m_argImpl;
|
||||||
const variable_if_dynamic<Index, (ArgType::RowsAtCompileTime == 1 && BlockRows==1) ? 0 : Dynamic> m_startRow;
|
const variable_if_dynamic<Index, (ArgType::RowsAtCompileTime == 1 && BlockRows==1) ? 0 : Dynamic> m_startRow;
|
||||||
const variable_if_dynamic<Index, (ArgType::ColsAtCompileTime == 1 && BlockCols==1) ? 0 : Dynamic> m_startCol;
|
const variable_if_dynamic<Index, (ArgType::ColsAtCompileTime == 1 && BlockCols==1) ? 0 : Dynamic> m_startCol;
|
||||||
const variable_if_dynamic<Index, InnerPanel ? Dynamic : 0> m_linear_offset;
|
const variable_if_dynamic<Index, ForwardLinearAccess ? Dynamic : 0> m_linear_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: This evaluator does not actually use the child evaluator;
|
// TODO: This evaluator does not actually use the child evaluator;
|
||||||
|
|
@ -1117,7 +1218,8 @@ struct block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel, /* HasDirectAc
|
||||||
typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
|
typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
|
||||||
typedef typename XprType::Scalar Scalar;
|
typedef typename XprType::Scalar Scalar;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit block_evaluator(const XprType& block)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
explicit block_evaluator(const XprType& block)
|
||||||
: mapbase_evaluator<XprType, typename XprType::PlainObject>(block)
|
: mapbase_evaluator<XprType, typename XprType::PlainObject>(block)
|
||||||
{
|
{
|
||||||
// TODO: for the 3.3 release, this should be turned to an internal assertion, but let's keep it as is for the beta lifetime
|
// TODO: for the 3.3 release, this should be turned to an internal assertion, but let's keep it as is for the beta lifetime
|
||||||
|
|
@ -1145,7 +1247,8 @@ struct evaluator<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >
|
||||||
Alignment = EIGEN_PLAIN_ENUM_MIN(evaluator<ThenMatrixType>::Alignment, evaluator<ElseMatrixType>::Alignment)
|
Alignment = EIGEN_PLAIN_ENUM_MIN(evaluator<ThenMatrixType>::Alignment, evaluator<ElseMatrixType>::Alignment)
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit evaluator(const XprType& select)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
explicit evaluator(const XprType& select)
|
||||||
: m_conditionImpl(select.conditionMatrix()),
|
: m_conditionImpl(select.conditionMatrix()),
|
||||||
m_thenImpl(select.thenMatrix()),
|
m_thenImpl(select.thenMatrix()),
|
||||||
m_elseImpl(select.elseMatrix())
|
m_elseImpl(select.elseMatrix())
|
||||||
|
|
@ -1202,7 +1305,8 @@ struct unary_evaluator<Replicate<ArgType, RowFactor, ColFactor> >
|
||||||
Alignment = evaluator<ArgTypeNestedCleaned>::Alignment
|
Alignment = evaluator<ArgTypeNestedCleaned>::Alignment
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& replicate)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
explicit unary_evaluator(const XprType& replicate)
|
||||||
: m_arg(replicate.nestedExpression()),
|
: m_arg(replicate.nestedExpression()),
|
||||||
m_argImpl(m_arg),
|
m_argImpl(m_arg),
|
||||||
m_rows(replicate.nestedExpression().rows()),
|
m_rows(replicate.nestedExpression().rows()),
|
||||||
|
|
@ -1266,64 +1370,6 @@ protected:
|
||||||
const variable_if_dynamic<Index, ArgType::ColsAtCompileTime> m_cols;
|
const variable_if_dynamic<Index, ArgType::ColsAtCompileTime> m_cols;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// -------------------- PartialReduxExpr --------------------
|
|
||||||
|
|
||||||
template< typename ArgType, typename MemberOp, int Direction>
|
|
||||||
struct evaluator<PartialReduxExpr<ArgType, MemberOp, Direction> >
|
|
||||||
: evaluator_base<PartialReduxExpr<ArgType, MemberOp, Direction> >
|
|
||||||
{
|
|
||||||
typedef PartialReduxExpr<ArgType, MemberOp, Direction> XprType;
|
|
||||||
typedef typename internal::nested_eval<ArgType,1>::type ArgTypeNested;
|
|
||||||
typedef typename internal::remove_all<ArgTypeNested>::type ArgTypeNestedCleaned;
|
|
||||||
typedef typename ArgType::Scalar InputScalar;
|
|
||||||
typedef typename XprType::Scalar Scalar;
|
|
||||||
enum {
|
|
||||||
TraversalSize = Direction==int(Vertical) ? int(ArgType::RowsAtCompileTime) : int(ArgType::ColsAtCompileTime)
|
|
||||||
};
|
|
||||||
typedef typename MemberOp::template Cost<InputScalar,int(TraversalSize)> CostOpType;
|
|
||||||
enum {
|
|
||||||
CoeffReadCost = TraversalSize==Dynamic ? HugeCost
|
|
||||||
: TraversalSize * evaluator<ArgType>::CoeffReadCost + int(CostOpType::value),
|
|
||||||
|
|
||||||
Flags = (traits<XprType>::Flags&RowMajorBit) | (evaluator<ArgType>::Flags&(HereditaryBits&(~RowMajorBit))) | LinearAccessBit,
|
|
||||||
|
|
||||||
Alignment = 0 // FIXME this will need to be improved once PartialReduxExpr is vectorized
|
|
||||||
};
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit evaluator(const XprType xpr)
|
|
||||||
: m_arg(xpr.nestedExpression()), m_functor(xpr.functor())
|
|
||||||
{
|
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(TraversalSize==Dynamic ? HugeCost : int(CostOpType::value));
|
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
const Scalar coeff(Index i, Index j) const
|
|
||||||
{
|
|
||||||
if (Direction==Vertical)
|
|
||||||
return m_functor(m_arg.col(j));
|
|
||||||
else
|
|
||||||
return m_functor(m_arg.row(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
|
||||||
const Scalar coeff(Index index) const
|
|
||||||
{
|
|
||||||
if (Direction==Vertical)
|
|
||||||
return m_functor(m_arg.col(index));
|
|
||||||
else
|
|
||||||
return m_functor(m_arg.row(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
typename internal::add_const_on_value_type<ArgTypeNested>::type m_arg;
|
|
||||||
const MemberOp m_functor;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------- MatrixWrapper and ArrayWrapper --------------------
|
// -------------------- MatrixWrapper and ArrayWrapper --------------------
|
||||||
//
|
//
|
||||||
// evaluator_wrapper_base<T> is a common base class for the
|
// evaluator_wrapper_base<T> is a common base class for the
|
||||||
|
|
@ -1340,7 +1386,8 @@ struct evaluator_wrapper_base
|
||||||
Alignment = evaluator<ArgType>::Alignment
|
Alignment = evaluator<ArgType>::Alignment
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit evaluator_wrapper_base(const ArgType& arg) : m_argImpl(arg) {}
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
explicit evaluator_wrapper_base(const ArgType& arg) : m_argImpl(arg) {}
|
||||||
|
|
||||||
typedef typename ArgType::Scalar Scalar;
|
typedef typename ArgType::Scalar Scalar;
|
||||||
typedef typename ArgType::CoeffReturnType CoeffReturnType;
|
typedef typename ArgType::CoeffReturnType CoeffReturnType;
|
||||||
|
|
@ -1407,7 +1454,8 @@ struct unary_evaluator<MatrixWrapper<TArgType> >
|
||||||
{
|
{
|
||||||
typedef MatrixWrapper<TArgType> XprType;
|
typedef MatrixWrapper<TArgType> XprType;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& wrapper)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
explicit unary_evaluator(const XprType& wrapper)
|
||||||
: evaluator_wrapper_base<MatrixWrapper<TArgType> >(wrapper.nestedExpression())
|
: evaluator_wrapper_base<MatrixWrapper<TArgType> >(wrapper.nestedExpression())
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
@ -1418,7 +1466,8 @@ struct unary_evaluator<ArrayWrapper<TArgType> >
|
||||||
{
|
{
|
||||||
typedef ArrayWrapper<TArgType> XprType;
|
typedef ArrayWrapper<TArgType> XprType;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& wrapper)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
explicit unary_evaluator(const XprType& wrapper)
|
||||||
: evaluator_wrapper_base<ArrayWrapper<TArgType> >(wrapper.nestedExpression())
|
: evaluator_wrapper_base<ArrayWrapper<TArgType> >(wrapper.nestedExpression())
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
@ -1460,7 +1509,8 @@ struct unary_evaluator<Reverse<ArgType, Direction> >
|
||||||
Alignment = 0 // FIXME in some rare cases, Alignment could be preserved, like a Vector4f.
|
Alignment = 0 // FIXME in some rare cases, Alignment could be preserved, like a Vector4f.
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& reverse)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
explicit unary_evaluator(const XprType& reverse)
|
||||||
: m_argImpl(reverse.nestedExpression()),
|
: m_argImpl(reverse.nestedExpression()),
|
||||||
m_rows(ReverseRow ? reverse.nestedExpression().rows() : 1),
|
m_rows(ReverseRow ? reverse.nestedExpression().rows() : 1),
|
||||||
m_cols(ReverseCol ? reverse.nestedExpression().cols() : 1)
|
m_cols(ReverseCol ? reverse.nestedExpression().cols() : 1)
|
||||||
|
|
@ -1567,7 +1617,8 @@ struct evaluator<Diagonal<ArgType, DiagIndex> >
|
||||||
Alignment = 0
|
Alignment = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit evaluator(const XprType& diagonal)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
explicit evaluator(const XprType& diagonal)
|
||||||
: m_argImpl(diagonal.nestedExpression()),
|
: m_argImpl(diagonal.nestedExpression()),
|
||||||
m_index(diagonal.index())
|
m_index(diagonal.index())
|
||||||
{ }
|
{ }
|
||||||
|
|
@ -1604,8 +1655,10 @@ protected:
|
||||||
const internal::variable_if_dynamicindex<Index, XprType::DiagIndex> m_index;
|
const internal::variable_if_dynamicindex<Index, XprType::DiagIndex> m_index;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rowOffset() const { return m_index.value() > 0 ? 0 : -m_index.value(); }
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index colOffset() const { return m_index.value() > 0 ? m_index.value() : 0; }
|
Index rowOffset() const { return m_index.value() > 0 ? 0 : -m_index.value(); }
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
|
Index colOffset() const { return m_index.value() > 0 ? m_index.value() : 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1642,12 +1695,12 @@ class EvalToTemp
|
||||||
return m_arg;
|
return m_arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
Index rows() const
|
EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
|
||||||
{
|
{
|
||||||
return m_arg.rows();
|
return m_arg.rows();
|
||||||
}
|
}
|
||||||
|
|
||||||
Index cols() const
|
EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT
|
||||||
{
|
{
|
||||||
return m_arg.cols();
|
return m_arg.cols();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,11 @@ public:
|
||||||
* Explicit zeros are not skipped over. To skip explicit zeros, see class SparseView
|
* Explicit zeros are not skipped over. To skip explicit zeros, see class SparseView
|
||||||
*/
|
*/
|
||||||
EIGEN_STRONG_INLINE InnerIterator& operator++() { m_iter.operator++(); return *this; }
|
EIGEN_STRONG_INLINE InnerIterator& operator++() { m_iter.operator++(); return *this; }
|
||||||
|
EIGEN_STRONG_INLINE InnerIterator& operator+=(Index i) { m_iter.operator+=(i); return *this; }
|
||||||
|
EIGEN_STRONG_INLINE InnerIterator operator+(Index i)
|
||||||
|
{ InnerIterator result(*this); result+=i; return result; }
|
||||||
|
|
||||||
|
|
||||||
/// \returns the column or row index of the current coefficient.
|
/// \returns the column or row index of the current coefficient.
|
||||||
EIGEN_STRONG_INLINE Index index() const { return m_iter.index(); }
|
EIGEN_STRONG_INLINE Index index() const { return m_iter.index(); }
|
||||||
/// \returns the row index of the current coefficient.
|
/// \returns the row index of the current coefficient.
|
||||||
|
|
|
||||||
|
|
@ -100,8 +100,14 @@ class CwiseBinaryOp :
|
||||||
typedef typename internal::remove_reference<LhsNested>::type _LhsNested;
|
typedef typename internal::remove_reference<LhsNested>::type _LhsNested;
|
||||||
typedef typename internal::remove_reference<RhsNested>::type _RhsNested;
|
typedef typename internal::remove_reference<RhsNested>::type _RhsNested;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
#if EIGEN_COMP_MSVC && EIGEN_HAS_CXX11
|
||||||
EIGEN_STRONG_INLINE CwiseBinaryOp(const Lhs& aLhs, const Rhs& aRhs, const BinaryOp& func = BinaryOp())
|
//Required for Visual Studio or the Copy constructor will probably not get inlined!
|
||||||
|
EIGEN_STRONG_INLINE
|
||||||
|
CwiseBinaryOp(const CwiseBinaryOp<BinaryOp,LhsType,RhsType>&) = default;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
CwiseBinaryOp(const Lhs& aLhs, const Rhs& aRhs, const BinaryOp& func = BinaryOp())
|
||||||
: m_lhs(aLhs), m_rhs(aRhs), m_functor(func)
|
: m_lhs(aLhs), m_rhs(aRhs), m_functor(func)
|
||||||
{
|
{
|
||||||
EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename Rhs::Scalar);
|
EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename Rhs::Scalar);
|
||||||
|
|
@ -110,31 +116,25 @@ class CwiseBinaryOp :
|
||||||
eigen_assert(aLhs.rows() == aRhs.rows() && aLhs.cols() == aRhs.cols());
|
eigen_assert(aLhs.rows() == aRhs.rows() && aLhs.cols() == aRhs.cols());
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
EIGEN_STRONG_INLINE Index rows() const {
|
Index rows() const EIGEN_NOEXCEPT {
|
||||||
// return the fixed size type if available to enable compile time optimizations
|
// return the fixed size type if available to enable compile time optimizations
|
||||||
if (internal::traits<typename internal::remove_all<LhsNested>::type>::RowsAtCompileTime==Dynamic)
|
return internal::traits<typename internal::remove_all<LhsNested>::type>::RowsAtCompileTime==Dynamic ? m_rhs.rows() : m_lhs.rows();
|
||||||
return m_rhs.rows();
|
|
||||||
else
|
|
||||||
return m_lhs.rows();
|
|
||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
EIGEN_STRONG_INLINE Index cols() const {
|
Index cols() const EIGEN_NOEXCEPT {
|
||||||
// return the fixed size type if available to enable compile time optimizations
|
// return the fixed size type if available to enable compile time optimizations
|
||||||
if (internal::traits<typename internal::remove_all<LhsNested>::type>::ColsAtCompileTime==Dynamic)
|
return internal::traits<typename internal::remove_all<LhsNested>::type>::ColsAtCompileTime==Dynamic ? m_rhs.cols() : 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
|
EIGEN_DEVICE_FUNC 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
|
EIGEN_DEVICE_FUNC 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
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
const BinaryOp& functor() const { return m_functor; }
|
const BinaryOp& functor() const { return m_functor; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -158,7 +158,7 @@ public:
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_STRONG_INLINE Derived &
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived &
|
||||||
MatrixBase<Derived>::operator-=(const MatrixBase<OtherDerived> &other)
|
MatrixBase<Derived>::operator-=(const MatrixBase<OtherDerived> &other)
|
||||||
{
|
{
|
||||||
call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar,typename OtherDerived::Scalar>());
|
call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar,typename OtherDerived::Scalar>());
|
||||||
|
|
@ -171,7 +171,7 @@ MatrixBase<Derived>::operator-=(const MatrixBase<OtherDerived> &other)
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_STRONG_INLINE Derived &
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived &
|
||||||
MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other)
|
MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other)
|
||||||
{
|
{
|
||||||
call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar,typename OtherDerived::Scalar>());
|
call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar,typename OtherDerived::Scalar>());
|
||||||
|
|
@ -181,4 +181,3 @@ MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other)
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_CWISE_BINARY_OP_H
|
#endif // EIGEN_CWISE_BINARY_OP_H
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,10 +74,10 @@ class CwiseNullaryOp : public internal::dense_xpr_base< CwiseNullaryOp<NullaryOp
|
||||||
&& (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
|
&& (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
EIGEN_STRONG_INLINE Index rows() const { return m_rows.value(); }
|
Index rows() const { return m_rows.value(); }
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
EIGEN_STRONG_INLINE Index cols() const { return m_cols.value(); }
|
Index cols() const { return m_cols.value(); }
|
||||||
|
|
||||||
/** \returns the functor representing the nullary operation */
|
/** \returns the functor representing the nullary operation */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
|
|
@ -105,7 +105,12 @@ class CwiseNullaryOp : public internal::dense_xpr_base< CwiseNullaryOp<NullaryOp
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename CustomNullaryOp>
|
template<typename CustomNullaryOp>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
const CwiseNullaryOp<CustomNullaryOp,typename DenseBase<Derived>::PlainObject>
|
||||||
|
#else
|
||||||
|
const CwiseNullaryOp<CustomNullaryOp,PlainObject>
|
||||||
|
#endif
|
||||||
DenseBase<Derived>::NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func)
|
DenseBase<Derived>::NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func)
|
||||||
{
|
{
|
||||||
return CwiseNullaryOp<CustomNullaryOp, PlainObject>(rows, cols, func);
|
return CwiseNullaryOp<CustomNullaryOp, PlainObject>(rows, cols, func);
|
||||||
|
|
@ -131,7 +136,12 @@ DenseBase<Derived>::NullaryExpr(Index rows, Index cols, const CustomNullaryOp& f
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename CustomNullaryOp>
|
template<typename CustomNullaryOp>
|
||||||
EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
|
||||||
|
#else
|
||||||
|
const CwiseNullaryOp<CustomNullaryOp, PlainObject>
|
||||||
|
#endif
|
||||||
DenseBase<Derived>::NullaryExpr(Index size, const CustomNullaryOp& func)
|
DenseBase<Derived>::NullaryExpr(Index size, const CustomNullaryOp& func)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
|
|
@ -150,7 +160,12 @@ DenseBase<Derived>::NullaryExpr(Index size, const CustomNullaryOp& func)
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename CustomNullaryOp>
|
template<typename CustomNullaryOp>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
|
||||||
|
#else
|
||||||
|
const CwiseNullaryOp<CustomNullaryOp, PlainObject>
|
||||||
|
#endif
|
||||||
DenseBase<Derived>::NullaryExpr(const CustomNullaryOp& func)
|
DenseBase<Derived>::NullaryExpr(const CustomNullaryOp& func)
|
||||||
{
|
{
|
||||||
return CwiseNullaryOp<CustomNullaryOp, PlainObject>(RowsAtCompileTime, ColsAtCompileTime, func);
|
return CwiseNullaryOp<CustomNullaryOp, PlainObject>(RowsAtCompileTime, ColsAtCompileTime, func);
|
||||||
|
|
@ -170,7 +185,7 @@ DenseBase<Derived>::NullaryExpr(const CustomNullaryOp& func)
|
||||||
* \sa class CwiseNullaryOp
|
* \sa class CwiseNullaryOp
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
|
||||||
DenseBase<Derived>::Constant(Index rows, Index cols, const Scalar& value)
|
DenseBase<Derived>::Constant(Index rows, Index cols, const Scalar& value)
|
||||||
{
|
{
|
||||||
return DenseBase<Derived>::NullaryExpr(rows, cols, internal::scalar_constant_op<Scalar>(value));
|
return DenseBase<Derived>::NullaryExpr(rows, cols, internal::scalar_constant_op<Scalar>(value));
|
||||||
|
|
@ -217,27 +232,32 @@ DenseBase<Derived>::Constant(const Scalar& value)
|
||||||
|
|
||||||
/** \deprecated because of accuracy loss. In Eigen 3.3, it is an alias for LinSpaced(Index,const Scalar&,const Scalar&)
|
/** \deprecated because of accuracy loss. In Eigen 3.3, it is an alias for LinSpaced(Index,const Scalar&,const Scalar&)
|
||||||
*
|
*
|
||||||
* \sa LinSpaced(Index,Scalar,Scalar), setLinSpaced(Index,const Scalar&,const Scalar&)
|
* \only_for_vectors
|
||||||
|
*
|
||||||
|
* Example: \include DenseBase_LinSpaced_seq_deprecated.cpp
|
||||||
|
* Output: \verbinclude DenseBase_LinSpaced_seq_deprecated.out
|
||||||
|
*
|
||||||
|
* \sa LinSpaced(Index,const Scalar&, const Scalar&), setLinSpaced(Index,const Scalar&,const Scalar&)
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
|
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
|
||||||
DenseBase<Derived>::LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high)
|
DenseBase<Derived>::LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar,PacketScalar>(low,high,size));
|
return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar>(low,high,size));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \deprecated because of accuracy loss. In Eigen 3.3, it is an alias for LinSpaced(const Scalar&,const Scalar&)
|
/** \deprecated because of accuracy loss. In Eigen 3.3, it is an alias for LinSpaced(const Scalar&,const Scalar&)
|
||||||
*
|
*
|
||||||
* \sa LinSpaced(Scalar,Scalar)
|
* \sa LinSpaced(const Scalar&, const Scalar&)
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
|
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
|
||||||
DenseBase<Derived>::LinSpaced(Sequential_t, const Scalar& low, const Scalar& high)
|
DenseBase<Derived>::LinSpaced(Sequential_t, const Scalar& low, const Scalar& high)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
|
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
|
||||||
return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar,PacketScalar>(low,high,Derived::SizeAtCompileTime));
|
return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar>(low,high,Derived::SizeAtCompileTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -268,7 +288,7 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomA
|
||||||
DenseBase<Derived>::LinSpaced(Index size, const Scalar& low, const Scalar& high)
|
DenseBase<Derived>::LinSpaced(Index size, const Scalar& low, const Scalar& high)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar,PacketScalar>(low,high,size));
|
return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar>(low,high,size));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -281,7 +301,7 @@ DenseBase<Derived>::LinSpaced(const Scalar& low, const Scalar& high)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
|
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
|
||||||
return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar,PacketScalar>(low,high,Derived::SizeAtCompileTime));
|
return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar>(low,high,Derived::SizeAtCompileTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns true if all coefficients in this matrix are approximately equal to \a val, to within precision \a prec */
|
/** \returns true if all coefficients in this matrix are approximately equal to \a val, to within precision \a prec */
|
||||||
|
|
@ -363,6 +383,33 @@ PlainObjectBase<Derived>::setConstant(Index rows, Index cols, const Scalar& val)
|
||||||
return setConstant(val);
|
return setConstant(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Resizes to the given size, changing only the number of columns, and sets all
|
||||||
|
* coefficients in this expression to the given value \a val. For the parameter
|
||||||
|
* of type NoChange_t, just pass the special value \c NoChange.
|
||||||
|
*
|
||||||
|
* \sa MatrixBase::setConstant(const Scalar&), setConstant(Index,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&)
|
||||||
|
*/
|
||||||
|
template<typename Derived>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
|
||||||
|
PlainObjectBase<Derived>::setConstant(NoChange_t, Index cols, const Scalar& val)
|
||||||
|
{
|
||||||
|
return setConstant(rows(), cols, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Resizes to the given size, changing only the number of rows, and sets all
|
||||||
|
* coefficients in this expression to the given value \a val. For the parameter
|
||||||
|
* of type NoChange_t, just pass the special value \c NoChange.
|
||||||
|
*
|
||||||
|
* \sa MatrixBase::setConstant(const Scalar&), setConstant(Index,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&)
|
||||||
|
*/
|
||||||
|
template<typename Derived>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
|
||||||
|
PlainObjectBase<Derived>::setConstant(Index rows, NoChange_t, const Scalar& val)
|
||||||
|
{
|
||||||
|
return setConstant(rows, cols(), val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Sets a linearly spaced vector.
|
* \brief Sets a linearly spaced vector.
|
||||||
*
|
*
|
||||||
|
|
@ -383,7 +430,7 @@ template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(Index newSize, const Scalar& low, const Scalar& high)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(Index newSize, const Scalar& low, const Scalar& high)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
return derived() = Derived::NullaryExpr(newSize, internal::linspaced_op<Scalar,PacketScalar>(low,high,newSize));
|
return derived() = Derived::NullaryExpr(newSize, internal::linspaced_op<Scalar>(low,high,newSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -536,6 +583,32 @@ PlainObjectBase<Derived>::setZero(Index rows, Index cols)
|
||||||
return setConstant(Scalar(0));
|
return setConstant(Scalar(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Resizes to the given size, changing only the number of columns, and sets all
|
||||||
|
* coefficients in this expression to zero. For the parameter of type NoChange_t,
|
||||||
|
* just pass the special value \c NoChange.
|
||||||
|
*
|
||||||
|
* \sa DenseBase::setZero(), setZero(Index), setZero(Index, Index), setZero(Index, NoChange_t), class CwiseNullaryOp, DenseBase::Zero()
|
||||||
|
*/
|
||||||
|
template<typename Derived>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
|
||||||
|
PlainObjectBase<Derived>::setZero(NoChange_t, Index cols)
|
||||||
|
{
|
||||||
|
return setZero(rows(), cols);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Resizes to the given size, changing only the number of rows, and sets all
|
||||||
|
* coefficients in this expression to zero. For the parameter of type NoChange_t,
|
||||||
|
* just pass the special value \c NoChange.
|
||||||
|
*
|
||||||
|
* \sa DenseBase::setZero(), setZero(Index), setZero(Index, Index), setZero(NoChange_t, Index), class CwiseNullaryOp, DenseBase::Zero()
|
||||||
|
*/
|
||||||
|
template<typename Derived>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
|
||||||
|
PlainObjectBase<Derived>::setZero(Index rows, NoChange_t)
|
||||||
|
{
|
||||||
|
return setZero(rows, cols());
|
||||||
|
}
|
||||||
|
|
||||||
// ones:
|
// ones:
|
||||||
|
|
||||||
/** \returns an expression of a matrix where all coefficients equal one.
|
/** \returns an expression of a matrix where all coefficients equal one.
|
||||||
|
|
@ -662,6 +735,32 @@ PlainObjectBase<Derived>::setOnes(Index rows, Index cols)
|
||||||
return setConstant(Scalar(1));
|
return setConstant(Scalar(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Resizes to the given size, changing only the number of rows, and sets all
|
||||||
|
* coefficients in this expression to one. For the parameter of type NoChange_t,
|
||||||
|
* just pass the special value \c NoChange.
|
||||||
|
*
|
||||||
|
* \sa MatrixBase::setOnes(), setOnes(Index), setOnes(Index, Index), setOnes(NoChange_t, Index), class CwiseNullaryOp, MatrixBase::Ones()
|
||||||
|
*/
|
||||||
|
template<typename Derived>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
|
||||||
|
PlainObjectBase<Derived>::setOnes(Index rows, NoChange_t)
|
||||||
|
{
|
||||||
|
return setOnes(rows, cols());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Resizes to the given size, changing only the number of columns, and sets all
|
||||||
|
* coefficients in this expression to one. For the parameter of type NoChange_t,
|
||||||
|
* just pass the special value \c NoChange.
|
||||||
|
*
|
||||||
|
* \sa MatrixBase::setOnes(), setOnes(Index), setOnes(Index, Index), setOnes(Index, NoChange_t) class CwiseNullaryOp, MatrixBase::Ones()
|
||||||
|
*/
|
||||||
|
template<typename Derived>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
|
||||||
|
PlainObjectBase<Derived>::setOnes(NoChange_t, Index cols)
|
||||||
|
{
|
||||||
|
return setOnes(rows(), cols);
|
||||||
|
}
|
||||||
|
|
||||||
// Identity:
|
// Identity:
|
||||||
|
|
||||||
/** \returns an expression of the identity matrix (not necessarily square).
|
/** \returns an expression of the identity matrix (not necessarily square).
|
||||||
|
|
@ -861,6 +960,42 @@ template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitW()
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitW()
|
||||||
{ return Derived::Unit(3); }
|
{ return Derived::Unit(3); }
|
||||||
|
|
||||||
|
/** \brief Set the coefficients of \c *this to the i-th unit (basis) vector
|
||||||
|
*
|
||||||
|
* \param i index of the unique coefficient to be set to 1
|
||||||
|
*
|
||||||
|
* \only_for_vectors
|
||||||
|
*
|
||||||
|
* \sa MatrixBase::setIdentity(), class CwiseNullaryOp, MatrixBase::Unit(Index,Index)
|
||||||
|
*/
|
||||||
|
template<typename Derived>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setUnit(Index i)
|
||||||
|
{
|
||||||
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
|
||||||
|
eigen_assert(i<size());
|
||||||
|
derived().setZero();
|
||||||
|
derived().coeffRef(i) = Scalar(1);
|
||||||
|
return derived();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief Resizes to the given \a newSize, and writes the i-th unit (basis) vector into *this.
|
||||||
|
*
|
||||||
|
* \param newSize the new size of the vector
|
||||||
|
* \param i index of the unique coefficient to be set to 1
|
||||||
|
*
|
||||||
|
* \only_for_vectors
|
||||||
|
*
|
||||||
|
* \sa MatrixBase::setIdentity(), class CwiseNullaryOp, MatrixBase::Unit(Index,Index)
|
||||||
|
*/
|
||||||
|
template<typename Derived>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setUnit(Index newSize, Index i)
|
||||||
|
{
|
||||||
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
|
||||||
|
eigen_assert(i<newSize);
|
||||||
|
derived().resize(newSize);
|
||||||
|
return setUnit(i);
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_CWISE_NULLARY_OP_H
|
#endif // EIGEN_CWISE_NULLARY_OP_H
|
||||||
|
|
|
||||||
|
|
@ -65,10 +65,10 @@ class CwiseUnaryOp : public CwiseUnaryOpImpl<UnaryOp, XprType, typename internal
|
||||||
explicit CwiseUnaryOp(const XprType& xpr, const UnaryOp& func = UnaryOp())
|
explicit CwiseUnaryOp(const XprType& xpr, const UnaryOp& func = UnaryOp())
|
||||||
: m_xpr(xpr), m_functor(func) {}
|
: m_xpr(xpr), m_functor(func) {}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
Index rows() const { return m_xpr.rows(); }
|
Index rows() const EIGEN_NOEXCEPT { return m_xpr.rows(); }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
Index cols() const { return m_xpr.cols(); }
|
Index cols() const EIGEN_NOEXCEPT { return m_xpr.cols(); }
|
||||||
|
|
||||||
/** \returns the functor representing the unary operation */
|
/** \returns the functor representing the unary operation */
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
|
|
||||||
|
|
@ -64,24 +64,26 @@ class CwiseUnaryView : public CwiseUnaryViewImpl<ViewOp, MatrixType, typename in
|
||||||
typedef typename internal::ref_selector<MatrixType>::non_const_type MatrixTypeNested;
|
typedef typename internal::ref_selector<MatrixType>::non_const_type MatrixTypeNested;
|
||||||
typedef typename internal::remove_all<MatrixType>::type NestedExpression;
|
typedef typename internal::remove_all<MatrixType>::type NestedExpression;
|
||||||
|
|
||||||
explicit inline CwiseUnaryView(MatrixType& mat, const ViewOp& func = ViewOp())
|
explicit EIGEN_DEVICE_FUNC inline CwiseUnaryView(MatrixType& mat, const ViewOp& func = ViewOp())
|
||||||
: m_matrix(mat), m_functor(func) {}
|
: m_matrix(mat), m_functor(func) {}
|
||||||
|
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryView)
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryView)
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE Index rows() const { return m_matrix.rows(); }
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
EIGEN_STRONG_INLINE Index cols() const { return m_matrix.cols(); }
|
Index rows() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
|
Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
|
||||||
|
|
||||||
/** \returns the functor representing unary operation */
|
/** \returns the functor representing unary operation */
|
||||||
const ViewOp& functor() const { return m_functor; }
|
EIGEN_DEVICE_FUNC const ViewOp& functor() const { return m_functor; }
|
||||||
|
|
||||||
/** \returns the nested expression */
|
/** \returns the nested expression */
|
||||||
const typename internal::remove_all<MatrixTypeNested>::type&
|
EIGEN_DEVICE_FUNC const typename internal::remove_all<MatrixTypeNested>::type&
|
||||||
nestedExpression() const { return m_matrix; }
|
nestedExpression() const { return m_matrix; }
|
||||||
|
|
||||||
/** \returns the nested expression */
|
/** \returns the nested expression */
|
||||||
typename internal::remove_reference<MatrixTypeNested>::type&
|
EIGEN_DEVICE_FUNC typename internal::remove_reference<MatrixTypeNested>::type&
|
||||||
nestedExpression() { return m_matrix.const_cast_derived(); }
|
nestedExpression() { return m_matrix; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MatrixTypeNested m_matrix;
|
MatrixTypeNested m_matrix;
|
||||||
|
|
@ -112,15 +114,17 @@ class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense>
|
||||||
EIGEN_DEVICE_FUNC inline Scalar* data() { return &(this->coeffRef(0)); }
|
EIGEN_DEVICE_FUNC inline Scalar* data() { return &(this->coeffRef(0)); }
|
||||||
EIGEN_DEVICE_FUNC inline const Scalar* data() const { return &(this->coeff(0)); }
|
EIGEN_DEVICE_FUNC inline const Scalar* data() const { return &(this->coeff(0)); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline Index innerStride() const
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index innerStride() const
|
||||||
{
|
{
|
||||||
return derived().nestedExpression().innerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar);
|
return derived().nestedExpression().innerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar);
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline Index outerStride() const
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index outerStride() const
|
||||||
{
|
{
|
||||||
return derived().nestedExpression().outerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar);
|
return derived().nestedExpression().outerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar);
|
||||||
}
|
}
|
||||||
|
protected:
|
||||||
|
EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(CwiseUnaryViewImpl)
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ namespace internal {
|
||||||
// The index type defined by EIGEN_DEFAULT_DENSE_INDEX_TYPE must be a signed type.
|
// The index type defined by EIGEN_DEFAULT_DENSE_INDEX_TYPE must be a signed type.
|
||||||
// This dummy function simply aims at checking that at compile time.
|
// This dummy function simply aims at checking that at compile time.
|
||||||
static inline void check_DenseIndex_is_signed() {
|
static inline void check_DenseIndex_is_signed() {
|
||||||
EIGEN_STATIC_ASSERT(NumTraits<DenseIndex>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE);
|
EIGEN_STATIC_ASSERT(NumTraits<DenseIndex>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE)
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
@ -40,7 +40,7 @@ static inline void check_DenseIndex_is_signed() {
|
||||||
*/
|
*/
|
||||||
template<typename Derived> class DenseBase
|
template<typename Derived> class DenseBase
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
: public DenseCoeffsBase<Derived>
|
: public DenseCoeffsBase<Derived, internal::accessors_level<Derived>::value>
|
||||||
#else
|
#else
|
||||||
: public DenseCoeffsBase<Derived,DirectWriteAccessors>
|
: public DenseCoeffsBase<Derived,DirectWriteAccessors>
|
||||||
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
|
@ -71,7 +71,7 @@ template<typename Derived> class DenseBase
|
||||||
typedef Scalar value_type;
|
typedef Scalar value_type;
|
||||||
|
|
||||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||||
typedef DenseCoeffsBase<Derived> Base;
|
typedef DenseCoeffsBase<Derived, internal::accessors_level<Derived>::value> Base;
|
||||||
|
|
||||||
using Base::derived;
|
using Base::derived;
|
||||||
using Base::const_cast_derived;
|
using Base::const_cast_derived;
|
||||||
|
|
@ -150,13 +150,18 @@ template<typename Derived> class DenseBase
|
||||||
* \sa SizeAtCompileTime, MaxRowsAtCompileTime, MaxColsAtCompileTime
|
* \sa SizeAtCompileTime, MaxRowsAtCompileTime, MaxColsAtCompileTime
|
||||||
*/
|
*/
|
||||||
|
|
||||||
IsVectorAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime == 1
|
IsVectorAtCompileTime = internal::traits<Derived>::RowsAtCompileTime == 1
|
||||||
|| internal::traits<Derived>::MaxColsAtCompileTime == 1,
|
|| internal::traits<Derived>::ColsAtCompileTime == 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".
|
||||||
|
|
@ -206,7 +211,7 @@ template<typename Derived> class DenseBase
|
||||||
|
|
||||||
/** \returns the number of nonzero coefficients which is in practice the number
|
/** \returns the number of nonzero coefficients which is in practice the number
|
||||||
* of stored coefficients. */
|
* of stored coefficients. */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index nonZeros() const { return size(); }
|
inline Index nonZeros() const { return size(); }
|
||||||
|
|
||||||
/** \returns the outer size.
|
/** \returns the outer size.
|
||||||
|
|
@ -214,7 +219,7 @@ template<typename Derived> class DenseBase
|
||||||
* \note For a vector, this returns just 1. For a matrix (non-vector), this is the major dimension
|
* \note For a vector, this returns just 1. For a matrix (non-vector), this is the major dimension
|
||||||
* with respect to the \ref TopicStorageOrders "storage order", i.e., the number of columns for a
|
* with respect to the \ref TopicStorageOrders "storage order", i.e., the number of columns for a
|
||||||
* column-major matrix, and the number of rows for a row-major matrix. */
|
* column-major matrix, and the number of rows for a row-major matrix. */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
Index outerSize() const
|
Index outerSize() const
|
||||||
{
|
{
|
||||||
return IsVectorAtCompileTime ? 1
|
return IsVectorAtCompileTime ? 1
|
||||||
|
|
@ -226,7 +231,7 @@ template<typename Derived> class DenseBase
|
||||||
* \note For a vector, this is just the size. For a matrix (non-vector), this is the minor dimension
|
* \note For a vector, this is just the size. For a matrix (non-vector), this is the minor dimension
|
||||||
* with respect to the \ref TopicStorageOrders "storage order", i.e., the number of rows for a
|
* with respect to the \ref TopicStorageOrders "storage order", i.e., the number of rows for a
|
||||||
* column-major matrix, and the number of columns for a row-major matrix. */
|
* column-major matrix, and the number of columns for a row-major matrix. */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
Index innerSize() const
|
Index innerSize() const
|
||||||
{
|
{
|
||||||
return IsVectorAtCompileTime ? this->size()
|
return IsVectorAtCompileTime ? this->size()
|
||||||
|
|
@ -261,9 +266,9 @@ template<typename Derived> class DenseBase
|
||||||
/** \internal Represents a matrix with all coefficients equal to one another*/
|
/** \internal Represents a matrix with all coefficients equal to one another*/
|
||||||
typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,PlainObject> ConstantReturnType;
|
typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,PlainObject> ConstantReturnType;
|
||||||
/** \internal \deprecated Represents a vector with linearly spaced coefficients that allows sequential access only. */
|
/** \internal \deprecated Represents a vector with linearly spaced coefficients that allows sequential access only. */
|
||||||
typedef CwiseNullaryOp<internal::linspaced_op<Scalar,PacketScalar>,PlainObject> SequentialLinSpacedReturnType;
|
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,PacketScalar>,PlainObject> RandomAccessLinSpacedReturnType;
|
typedef CwiseNullaryOp<internal::linspaced_op<Scalar>,PlainObject> RandomAccessLinSpacedReturnType;
|
||||||
/** \internal the return type of MatrixBase::eigenvalues() */
|
/** \internal the return type of MatrixBase::eigenvalues() */
|
||||||
typedef Matrix<typename NumTraits<typename internal::traits<Derived>::Scalar>::Real, internal::traits<Derived>::ColsAtCompileTime, 1> EigenvaluesReturnType;
|
typedef Matrix<typename NumTraits<typename internal::traits<Derived>::Scalar>::Real, internal::traits<Derived>::ColsAtCompileTime, 1> EigenvaluesReturnType;
|
||||||
|
|
||||||
|
|
@ -297,17 +302,17 @@ template<typename Derived> class DenseBase
|
||||||
Derived& operator=(const ReturnByValue<OtherDerived>& func);
|
Derived& operator=(const ReturnByValue<OtherDerived>& func);
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
* Copies \a other into *this without evaluating other. \returns a reference to *this.
|
* Copies \a other into *this without evaluating other. \returns a reference to *this. */
|
||||||
* \deprecated */
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
/** \deprecated */
|
||||||
|
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC
|
||||||
Derived& lazyAssign(const DenseBase<OtherDerived>& other);
|
Derived& lazyAssign(const DenseBase<OtherDerived>& other);
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
CommaInitializer<Derived> operator<< (const Scalar& s);
|
CommaInitializer<Derived> operator<< (const Scalar& s);
|
||||||
|
|
||||||
/** \deprecated it now returns \c *this */
|
|
||||||
template<unsigned int Added,unsigned int Removed>
|
template<unsigned int Added,unsigned int Removed>
|
||||||
|
/** \deprecated it now returns \c *this */
|
||||||
EIGEN_DEPRECATED
|
EIGEN_DEPRECATED
|
||||||
const Derived& flagged() const
|
const Derived& flagged() const
|
||||||
{ return derived(); }
|
{ return derived(); }
|
||||||
|
|
@ -332,12 +337,13 @@ template<typename Derived> class DenseBase
|
||||||
EIGEN_DEVICE_FUNC static const ConstantReturnType
|
EIGEN_DEVICE_FUNC static const ConstantReturnType
|
||||||
Constant(const Scalar& value);
|
Constant(const Scalar& value);
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC static const SequentialLinSpacedReturnType
|
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType
|
||||||
LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high);
|
LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high);
|
||||||
|
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType
|
||||||
|
LinSpaced(Sequential_t, const Scalar& low, const Scalar& high);
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType
|
EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType
|
||||||
LinSpaced(Index size, const Scalar& low, const Scalar& high);
|
LinSpaced(Index size, const Scalar& low, const Scalar& high);
|
||||||
EIGEN_DEVICE_FUNC static const SequentialLinSpacedReturnType
|
|
||||||
LinSpaced(Sequential_t, const Scalar& low, const Scalar& high);
|
|
||||||
EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType
|
EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType
|
||||||
LinSpaced(const Scalar& low, const Scalar& high);
|
LinSpaced(const Scalar& low, const Scalar& high);
|
||||||
|
|
||||||
|
|
@ -395,7 +401,7 @@ template<typename Derived> class DenseBase
|
||||||
* Notice that in the case of a plain matrix or vector (not an expression) this function just returns
|
* Notice that in the case of a plain matrix or vector (not an expression) this function just returns
|
||||||
* a const reference, in order to avoid a useless copy.
|
* a const reference, in order to avoid a useless copy.
|
||||||
*
|
*
|
||||||
* \warning Be carefull with eval() and the auto C++ keyword, as detailed in this \link TopicPitfalls_auto_keyword page \endlink.
|
* \warning Be careful with eval() and the auto C++ keyword, as detailed in this \link TopicPitfalls_auto_keyword page \endlink.
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
EIGEN_STRONG_INLINE EvalReturnType eval() const
|
EIGEN_STRONG_INLINE EvalReturnType eval() const
|
||||||
|
|
@ -410,7 +416,7 @@ template<typename Derived> class DenseBase
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
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);
|
EIGEN_STATIC_ASSERT(!OtherDerived::IsPlainObjectBase,THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
|
||||||
|
|
@ -422,7 +428,7 @@ template<typename Derived> class DenseBase
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
void swap(PlainObjectBase<OtherDerived>& other)
|
void swap(PlainObjectBase<OtherDerived>& other)
|
||||||
{
|
{
|
||||||
eigen_assert(rows()==other.rows() && cols()==other.cols());
|
eigen_assert(rows()==other.rows() && cols()==other.cols());
|
||||||
|
|
@ -443,18 +449,58 @@ template<typename Derived> class DenseBase
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC Scalar prod() const;
|
EIGEN_DEVICE_FUNC Scalar prod() const;
|
||||||
|
|
||||||
|
template<int NaNPropagation>
|
||||||
EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar minCoeff() const;
|
EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar minCoeff() const;
|
||||||
|
template<int NaNPropagation>
|
||||||
EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar maxCoeff() const;
|
EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar maxCoeff() const;
|
||||||
|
|
||||||
template<typename IndexType> EIGEN_DEVICE_FUNC
|
|
||||||
|
// By default, the fastest version with undefined NaN propagation semantics is
|
||||||
|
// used.
|
||||||
|
// TODO(rmlarsen): Replace with default template argument when we move to
|
||||||
|
// c++11 or beyond.
|
||||||
|
EIGEN_DEVICE_FUNC inline typename internal::traits<Derived>::Scalar minCoeff() const {
|
||||||
|
return minCoeff<PropagateFast>();
|
||||||
|
}
|
||||||
|
EIGEN_DEVICE_FUNC inline typename internal::traits<Derived>::Scalar maxCoeff() const {
|
||||||
|
return maxCoeff<PropagateFast>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int NaNPropagation, typename IndexType>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
typename internal::traits<Derived>::Scalar minCoeff(IndexType* row, IndexType* col) const;
|
typename internal::traits<Derived>::Scalar minCoeff(IndexType* row, IndexType* col) const;
|
||||||
template<typename IndexType> EIGEN_DEVICE_FUNC
|
template<int NaNPropagation, typename IndexType>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
typename internal::traits<Derived>::Scalar maxCoeff(IndexType* row, IndexType* col) const;
|
typename internal::traits<Derived>::Scalar maxCoeff(IndexType* row, IndexType* col) const;
|
||||||
template<typename IndexType> EIGEN_DEVICE_FUNC
|
template<int NaNPropagation, typename IndexType>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
typename internal::traits<Derived>::Scalar minCoeff(IndexType* index) const;
|
typename internal::traits<Derived>::Scalar minCoeff(IndexType* index) const;
|
||||||
template<typename IndexType> EIGEN_DEVICE_FUNC
|
template<int NaNPropagation, typename IndexType>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
typename internal::traits<Derived>::Scalar maxCoeff(IndexType* index) const;
|
typename internal::traits<Derived>::Scalar maxCoeff(IndexType* index) const;
|
||||||
|
|
||||||
|
// TODO(rmlarsen): Replace these methods with a default template argument.
|
||||||
|
template<typename IndexType>
|
||||||
|
EIGEN_DEVICE_FUNC inline
|
||||||
|
typename internal::traits<Derived>::Scalar minCoeff(IndexType* row, IndexType* col) const {
|
||||||
|
return minCoeff<PropagateFast>(row, col);
|
||||||
|
}
|
||||||
|
template<typename IndexType>
|
||||||
|
EIGEN_DEVICE_FUNC inline
|
||||||
|
typename internal::traits<Derived>::Scalar maxCoeff(IndexType* row, IndexType* col) const {
|
||||||
|
return maxCoeff<PropagateFast>(row, col);
|
||||||
|
}
|
||||||
|
template<typename IndexType>
|
||||||
|
EIGEN_DEVICE_FUNC inline
|
||||||
|
typename internal::traits<Derived>::Scalar minCoeff(IndexType* index) const {
|
||||||
|
return minCoeff<PropagateFast>(index);
|
||||||
|
}
|
||||||
|
template<typename IndexType>
|
||||||
|
EIGEN_DEVICE_FUNC inline
|
||||||
|
typename internal::traits<Derived>::Scalar maxCoeff(IndexType* index) const {
|
||||||
|
return maxCoeff<PropagateFast>(index);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename BinaryOp>
|
template<typename BinaryOp>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
Scalar redux(const BinaryOp& func) const;
|
Scalar redux(const BinaryOp& func) const;
|
||||||
|
|
@ -493,7 +539,7 @@ template<typename Derived> class DenseBase
|
||||||
typedef VectorwiseOp<Derived, Vertical> ColwiseReturnType;
|
typedef VectorwiseOp<Derived, Vertical> ColwiseReturnType;
|
||||||
typedef const VectorwiseOp<const Derived, Vertical> ConstColwiseReturnType;
|
typedef const VectorwiseOp<const Derived, Vertical> ConstColwiseReturnType;
|
||||||
|
|
||||||
/** \returns a VectorwiseOp wrapper of *this providing additional partial reduction operations
|
/** \returns a VectorwiseOp wrapper of *this for broadcasting and partial reductions
|
||||||
*
|
*
|
||||||
* Example: \include MatrixBase_rowwise.cpp
|
* Example: \include MatrixBase_rowwise.cpp
|
||||||
* Output: \verbinclude MatrixBase_rowwise.out
|
* Output: \verbinclude MatrixBase_rowwise.out
|
||||||
|
|
@ -506,7 +552,7 @@ template<typename Derived> class DenseBase
|
||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC RowwiseReturnType rowwise();
|
EIGEN_DEVICE_FUNC RowwiseReturnType rowwise();
|
||||||
|
|
||||||
/** \returns a VectorwiseOp wrapper of *this providing additional partial reduction operations
|
/** \returns a VectorwiseOp wrapper of *this broadcasting and partial reductions
|
||||||
*
|
*
|
||||||
* Example: \include MatrixBase_colwise.cpp
|
* Example: \include MatrixBase_colwise.cpp
|
||||||
* Output: \verbinclude MatrixBase_colwise.out
|
* Output: \verbinclude MatrixBase_colwise.out
|
||||||
|
|
@ -524,16 +570,16 @@ template<typename Derived> class DenseBase
|
||||||
static const RandomReturnType Random();
|
static const RandomReturnType Random();
|
||||||
|
|
||||||
template<typename ThenDerived,typename ElseDerived>
|
template<typename ThenDerived,typename ElseDerived>
|
||||||
const Select<Derived,ThenDerived,ElseDerived>
|
inline EIGEN_DEVICE_FUNC const Select<Derived,ThenDerived,ElseDerived>
|
||||||
select(const DenseBase<ThenDerived>& thenMatrix,
|
select(const DenseBase<ThenDerived>& thenMatrix,
|
||||||
const DenseBase<ElseDerived>& elseMatrix) const;
|
const DenseBase<ElseDerived>& elseMatrix) const;
|
||||||
|
|
||||||
template<typename ThenDerived>
|
template<typename ThenDerived>
|
||||||
inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
|
inline EIGEN_DEVICE_FUNC const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
|
||||||
select(const DenseBase<ThenDerived>& thenMatrix, const typename ThenDerived::Scalar& elseScalar) const;
|
select(const DenseBase<ThenDerived>& thenMatrix, const typename ThenDerived::Scalar& elseScalar) const;
|
||||||
|
|
||||||
template<typename ElseDerived>
|
template<typename ElseDerived>
|
||||||
inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
|
inline EIGEN_DEVICE_FUNC const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
|
||||||
select(const typename ElseDerived::Scalar& thenScalar, const DenseBase<ElseDerived>& elseMatrix) const;
|
select(const typename ElseDerived::Scalar& thenScalar, const DenseBase<ElseDerived>& elseMatrix) const;
|
||||||
|
|
||||||
template<int p> RealScalar lpNorm() const;
|
template<int p> RealScalar lpNorm() const;
|
||||||
|
|
@ -567,16 +613,59 @@ template<typename Derived> class DenseBase
|
||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC void reverseInPlace();
|
EIGEN_DEVICE_FUNC void reverseInPlace();
|
||||||
|
|
||||||
|
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
/** STL-like <a href="https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator">RandomAccessIterator</a>
|
||||||
|
* iterator type as returned by the begin() and end() methods.
|
||||||
|
*/
|
||||||
|
typedef random_access_iterator_type iterator;
|
||||||
|
/** This is the const version of iterator (aka read-only) */
|
||||||
|
typedef random_access_iterator_type const_iterator;
|
||||||
|
#else
|
||||||
|
typedef typename internal::conditional< (Flags&DirectAccessBit)==DirectAccessBit,
|
||||||
|
internal::pointer_based_stl_iterator<Derived>,
|
||||||
|
internal::generic_randaccess_stl_iterator<Derived>
|
||||||
|
>::type iterator_type;
|
||||||
|
|
||||||
|
typedef typename internal::conditional< (Flags&DirectAccessBit)==DirectAccessBit,
|
||||||
|
internal::pointer_based_stl_iterator<const Derived>,
|
||||||
|
internal::generic_randaccess_stl_iterator<const Derived>
|
||||||
|
>::type const_iterator_type;
|
||||||
|
|
||||||
|
// Stl-style iterators are supported only for vectors.
|
||||||
|
|
||||||
|
typedef typename internal::conditional< IsVectorAtCompileTime,
|
||||||
|
iterator_type,
|
||||||
|
void
|
||||||
|
>::type iterator;
|
||||||
|
|
||||||
|
typedef typename internal::conditional< IsVectorAtCompileTime,
|
||||||
|
const_iterator_type,
|
||||||
|
void
|
||||||
|
>::type const_iterator;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline iterator begin();
|
||||||
|
inline const_iterator begin() const;
|
||||||
|
inline const_iterator cbegin() const;
|
||||||
|
inline iterator end();
|
||||||
|
inline const_iterator end() const;
|
||||||
|
inline const_iterator cend() const;
|
||||||
|
|
||||||
#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::DenseBase
|
#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::DenseBase
|
||||||
#define EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
|
#define EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
|
||||||
#define EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(COND)
|
#define EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(COND)
|
||||||
|
#define EIGEN_DOC_UNARY_ADDONS(X,Y)
|
||||||
|
# include "../plugins/CommonCwiseUnaryOps.h"
|
||||||
# include "../plugins/BlockMethods.h"
|
# include "../plugins/BlockMethods.h"
|
||||||
|
# include "../plugins/IndexedViewMethods.h"
|
||||||
|
# include "../plugins/ReshapedMethods.h"
|
||||||
# ifdef EIGEN_DENSEBASE_PLUGIN
|
# ifdef EIGEN_DENSEBASE_PLUGIN
|
||||||
# include EIGEN_DENSEBASE_PLUGIN
|
# include EIGEN_DENSEBASE_PLUGIN
|
||||||
# endif
|
# endif
|
||||||
#undef EIGEN_CURRENT_STORAGE_BASE_CLASS
|
#undef EIGEN_CURRENT_STORAGE_BASE_CLASS
|
||||||
#undef EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
|
#undef EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
|
||||||
#undef EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF
|
#undef EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF
|
||||||
|
#undef EIGEN_DOC_UNARY_ADDONS
|
||||||
|
|
||||||
// disable the use of evalTo for dense objects with a nice compilation error
|
// disable the use of evalTo for dense objects with a nice compilation error
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
|
|
@ -587,11 +676,12 @@ template<typename Derived> class DenseBase
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
EIGEN_DEFAULT_COPY_CONSTRUCTOR(DenseBase)
|
||||||
/** Default constructor. Do nothing. */
|
/** Default constructor. Do nothing. */
|
||||||
EIGEN_DEVICE_FUNC DenseBase()
|
EIGEN_DEVICE_FUNC 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 paranoiac and could slow compilation down
|
* Only do it when debugging Eigen, as this borders on paranoia and could slow compilation down
|
||||||
*/
|
*/
|
||||||
#ifdef EIGEN_INTERNAL_DEBUGGING
|
#ifdef EIGEN_INTERNAL_DEBUGGING
|
||||||
EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, int(IsRowMajor))
|
EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, int(IsRowMajor))
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,8 @@ template<typename T> struct add_const_on_value_type_if_arithmetic
|
||||||
/** \brief Base class providing read-only coefficient access to matrices and arrays.
|
/** \brief Base class providing read-only coefficient access to matrices and arrays.
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
* \tparam Derived Type of the derived class
|
* \tparam Derived Type of the derived class
|
||||||
* \tparam #ReadOnlyAccessors Constant indicating read-only access
|
*
|
||||||
|
* \note #ReadOnlyAccessors Constant indicating read-only access
|
||||||
*
|
*
|
||||||
* This class defines the \c operator() \c const function and friends, which can be used to read specific
|
* This class defines the \c operator() \c const function and friends, which can be used to read specific
|
||||||
* entries of a matrix or array.
|
* entries of a matrix or array.
|
||||||
|
|
@ -288,7 +289,8 @@ 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
|
||||||
|
|
@ -466,7 +468,8 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
||||||
/** \brief Base class providing direct read-only coefficient access to matrices and arrays.
|
/** \brief Base class providing direct read-only coefficient access to matrices and arrays.
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
* \tparam Derived Type of the derived class
|
* \tparam Derived Type of the derived class
|
||||||
* \tparam #DirectAccessors Constant indicating direct access
|
*
|
||||||
|
* \note #DirectAccessors Constant indicating direct access
|
||||||
*
|
*
|
||||||
* This class defines functions to work with strides which can be used to access entries directly. This class
|
* This class defines functions to work with strides which can be used to access entries directly. This class
|
||||||
* inherits DenseCoeffsBase<Derived, ReadOnlyAccessors> which defines functions to access entries read-only using
|
* inherits DenseCoeffsBase<Derived, ReadOnlyAccessors> which defines functions to access entries read-only using
|
||||||
|
|
@ -492,7 +495,7 @@ class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived
|
||||||
*
|
*
|
||||||
* \sa outerStride(), rowStride(), colStride()
|
* \sa outerStride(), rowStride(), colStride()
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index innerStride() const
|
inline Index innerStride() const
|
||||||
{
|
{
|
||||||
return derived().innerStride();
|
return derived().innerStride();
|
||||||
|
|
@ -503,14 +506,14 @@ class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived
|
||||||
*
|
*
|
||||||
* \sa innerStride(), rowStride(), colStride()
|
* \sa innerStride(), rowStride(), colStride()
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index outerStride() const
|
inline Index outerStride() const
|
||||||
{
|
{
|
||||||
return derived().outerStride();
|
return derived().outerStride();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME shall we remove it ?
|
// FIXME shall we remove it ?
|
||||||
inline Index stride() const
|
EIGEN_CONSTEXPR inline Index stride() const
|
||||||
{
|
{
|
||||||
return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
|
return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
|
||||||
}
|
}
|
||||||
|
|
@ -519,7 +522,7 @@ class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived
|
||||||
*
|
*
|
||||||
* \sa innerStride(), outerStride(), colStride()
|
* \sa innerStride(), outerStride(), colStride()
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index rowStride() const
|
inline Index rowStride() const
|
||||||
{
|
{
|
||||||
return Derived::IsRowMajor ? outerStride() : innerStride();
|
return Derived::IsRowMajor ? outerStride() : innerStride();
|
||||||
|
|
@ -529,7 +532,7 @@ class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived
|
||||||
*
|
*
|
||||||
* \sa innerStride(), outerStride(), rowStride()
|
* \sa innerStride(), outerStride(), rowStride()
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index colStride() const
|
inline Index colStride() const
|
||||||
{
|
{
|
||||||
return Derived::IsRowMajor ? innerStride() : outerStride();
|
return Derived::IsRowMajor ? innerStride() : outerStride();
|
||||||
|
|
@ -539,7 +542,8 @@ class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived
|
||||||
/** \brief Base class providing direct read/write coefficient access to matrices and arrays.
|
/** \brief Base class providing direct read/write coefficient access to matrices and arrays.
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
* \tparam Derived Type of the derived class
|
* \tparam Derived Type of the derived class
|
||||||
* \tparam #DirectWriteAccessors Constant indicating direct access
|
*
|
||||||
|
* \note #DirectWriteAccessors Constant indicating direct access
|
||||||
*
|
*
|
||||||
* This class defines functions to work with strides which can be used to access entries directly. This class
|
* This class defines functions to work with strides which can be used to access entries directly. This class
|
||||||
* inherits DenseCoeffsBase<Derived, WriteAccessors> which defines functions to access entries read/write using
|
* inherits DenseCoeffsBase<Derived, WriteAccessors> which defines functions to access entries read/write using
|
||||||
|
|
@ -566,8 +570,8 @@ class DenseCoeffsBase<Derived, DirectWriteAccessors>
|
||||||
*
|
*
|
||||||
* \sa outerStride(), rowStride(), colStride()
|
* \sa outerStride(), rowStride(), colStride()
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index innerStride() const
|
inline Index innerStride() const EIGEN_NOEXCEPT
|
||||||
{
|
{
|
||||||
return derived().innerStride();
|
return derived().innerStride();
|
||||||
}
|
}
|
||||||
|
|
@ -577,14 +581,14 @@ class DenseCoeffsBase<Derived, DirectWriteAccessors>
|
||||||
*
|
*
|
||||||
* \sa innerStride(), rowStride(), colStride()
|
* \sa innerStride(), rowStride(), colStride()
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index outerStride() const
|
inline Index outerStride() const EIGEN_NOEXCEPT
|
||||||
{
|
{
|
||||||
return derived().outerStride();
|
return derived().outerStride();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME shall we remove it ?
|
// FIXME shall we remove it ?
|
||||||
inline Index stride() const
|
EIGEN_CONSTEXPR inline Index stride() const EIGEN_NOEXCEPT
|
||||||
{
|
{
|
||||||
return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
|
return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
|
||||||
}
|
}
|
||||||
|
|
@ -593,8 +597,8 @@ class DenseCoeffsBase<Derived, DirectWriteAccessors>
|
||||||
*
|
*
|
||||||
* \sa innerStride(), outerStride(), colStride()
|
* \sa innerStride(), outerStride(), colStride()
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index rowStride() const
|
inline Index rowStride() const EIGEN_NOEXCEPT
|
||||||
{
|
{
|
||||||
return Derived::IsRowMajor ? outerStride() : innerStride();
|
return Derived::IsRowMajor ? outerStride() : innerStride();
|
||||||
}
|
}
|
||||||
|
|
@ -603,8 +607,8 @@ class DenseCoeffsBase<Derived, DirectWriteAccessors>
|
||||||
*
|
*
|
||||||
* \sa innerStride(), outerStride(), rowStride()
|
* \sa innerStride(), outerStride(), rowStride()
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index colStride() const
|
inline Index colStride() const EIGEN_NOEXCEPT
|
||||||
{
|
{
|
||||||
return Derived::IsRowMajor ? innerStride() : outerStride();
|
return Derived::IsRowMajor ? innerStride() : outerStride();
|
||||||
}
|
}
|
||||||
|
|
@ -615,7 +619,7 @@ namespace internal {
|
||||||
template<int Alignment, typename Derived, bool JustReturnZero>
|
template<int Alignment, typename Derived, bool JustReturnZero>
|
||||||
struct first_aligned_impl
|
struct first_aligned_impl
|
||||||
{
|
{
|
||||||
static inline Index run(const Derived&)
|
static EIGEN_CONSTEXPR inline Index run(const Derived&) EIGEN_NOEXCEPT
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ struct plain_array
|
||||||
#if defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT)
|
#if defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT)
|
||||||
#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask)
|
#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask)
|
||||||
#elif EIGEN_GNUC_AT_LEAST(4,7)
|
#elif EIGEN_GNUC_AT_LEAST(4,7)
|
||||||
// GCC 4.7 is too aggressive in its optimizations and remove the alignement test based on the fact the array is declared to be aligned.
|
// GCC 4.7 is too aggressive in its optimizations and remove the alignment test based on the fact the array is declared to be aligned.
|
||||||
// See this bug report: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53900
|
// See this bug report: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53900
|
||||||
// Hiding the origin of the array pointer behind a function argument seems to do the trick even if the function is inlined:
|
// Hiding the origin of the array pointer behind a function argument seems to do the trick even if the function is inlined:
|
||||||
template<typename PtrType>
|
template<typename PtrType>
|
||||||
|
|
@ -163,6 +163,30 @@ struct plain_array<T, 0, MatrixOrArrayOptions, Alignment>
|
||||||
EIGEN_DEVICE_FUNC plain_array(constructor_without_unaligned_array_assert) {}
|
EIGEN_DEVICE_FUNC plain_array(constructor_without_unaligned_array_assert) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct plain_array_helper {
|
||||||
|
template<typename T, int Size, int MatrixOrArrayOptions, int Alignment>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
static void copy(const plain_array<T, Size, MatrixOrArrayOptions, Alignment>& src, const Eigen::Index size,
|
||||||
|
plain_array<T, Size, MatrixOrArrayOptions, Alignment>& dst) {
|
||||||
|
smart_copy(src.array, src.array + size, dst.array);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, int Size, int MatrixOrArrayOptions, int Alignment>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
static void swap(plain_array<T, Size, MatrixOrArrayOptions, Alignment>& a, const Eigen::Index a_size,
|
||||||
|
plain_array<T, Size, MatrixOrArrayOptions, Alignment>& b, const Eigen::Index b_size) {
|
||||||
|
if (a_size < b_size) {
|
||||||
|
std::swap_ranges(b.array, b.array + a_size, a.array);
|
||||||
|
smart_move(b.array + a_size, b.array + b_size, a.array + a_size);
|
||||||
|
} else if (a_size > b_size) {
|
||||||
|
std::swap_ranges(a.array, a.array + b_size, b.array);
|
||||||
|
smart_move(a.array + b_size, a.array + a_size, b.array + b_size);
|
||||||
|
} else {
|
||||||
|
std::swap_ranges(a.array, a.array + a_size, b.array);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
|
|
@ -190,16 +214,41 @@ template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseSt
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
|
explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||||
: m_data(internal::constructor_without_unaligned_array_assert()) {}
|
: m_data(internal::constructor_without_unaligned_array_assert()) {}
|
||||||
|
#if !EIGEN_HAS_CXX11 || defined(EIGEN_DENSE_STORAGE_CTOR_PLUGIN)
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
DenseStorage(const DenseStorage& other) : m_data(other.m_data) {
|
DenseStorage(const DenseStorage& other) : m_data(other.m_data) {
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size)
|
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size)
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage&) = default;
|
||||||
|
#endif
|
||||||
|
#if !EIGEN_HAS_CXX11
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
DenseStorage& operator=(const DenseStorage& other)
|
DenseStorage& operator=(const DenseStorage& other)
|
||||||
{
|
{
|
||||||
if (this != &other) m_data = other.m_data;
|
if (this != &other) m_data = other.m_data;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage&) = default;
|
||||||
|
#endif
|
||||||
|
#if EIGEN_HAS_RVALUE_REFERENCES
|
||||||
|
#if !EIGEN_HAS_CXX11
|
||||||
|
EIGEN_DEVICE_FUNC DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT
|
||||||
|
: m_data(std::move(other.m_data))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
EIGEN_DEVICE_FUNC DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
|
||||||
|
{
|
||||||
|
if (this != &other)
|
||||||
|
m_data = std::move(other.m_data);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
EIGEN_DEVICE_FUNC DenseStorage(DenseStorage&&) = default;
|
||||||
|
EIGEN_DEVICE_FUNC DenseStorage& operator=(DenseStorage&&) = default;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) {
|
EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) {
|
||||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
|
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
|
||||||
eigen_internal_assert(size==rows*cols && rows==_Rows && cols==_Cols);
|
eigen_internal_assert(size==rows*cols && rows==_Rows && cols==_Cols);
|
||||||
|
|
@ -207,9 +256,11 @@ template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseSt
|
||||||
EIGEN_UNUSED_VARIABLE(rows);
|
EIGEN_UNUSED_VARIABLE(rows);
|
||||||
EIGEN_UNUSED_VARIABLE(cols);
|
EIGEN_UNUSED_VARIABLE(cols);
|
||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); }
|
EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
|
||||||
EIGEN_DEVICE_FUNC static Index rows(void) {return _Rows;}
|
numext::swap(m_data, other.m_data);
|
||||||
EIGEN_DEVICE_FUNC static Index cols(void) {return _Cols;}
|
}
|
||||||
|
EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index rows(void) EIGEN_NOEXCEPT {return _Rows;}
|
||||||
|
EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index cols(void) EIGEN_NOEXCEPT {return _Cols;}
|
||||||
EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {}
|
EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {}
|
||||||
EIGEN_DEVICE_FUNC void resize(Index,Index,Index) {}
|
EIGEN_DEVICE_FUNC void resize(Index,Index,Index) {}
|
||||||
EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
|
EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
|
||||||
|
|
@ -226,8 +277,8 @@ template<typename T, int _Rows, int _Cols, int _Options> class DenseStorage<T, 0
|
||||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage&) { return *this; }
|
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage&) { return *this; }
|
||||||
EIGEN_DEVICE_FUNC DenseStorage(Index,Index,Index) {}
|
EIGEN_DEVICE_FUNC DenseStorage(Index,Index,Index) {}
|
||||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& ) {}
|
EIGEN_DEVICE_FUNC void swap(DenseStorage& ) {}
|
||||||
EIGEN_DEVICE_FUNC static Index rows(void) {return _Rows;}
|
EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index rows(void) EIGEN_NOEXCEPT {return _Rows;}
|
||||||
EIGEN_DEVICE_FUNC static Index cols(void) {return _Cols;}
|
EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index cols(void) EIGEN_NOEXCEPT {return _Cols;}
|
||||||
EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {}
|
EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {}
|
||||||
EIGEN_DEVICE_FUNC void resize(Index,Index,Index) {}
|
EIGEN_DEVICE_FUNC void resize(Index,Index,Index) {}
|
||||||
EIGEN_DEVICE_FUNC const T *data() const { return 0; }
|
EIGEN_DEVICE_FUNC const T *data() const { return 0; }
|
||||||
|
|
@ -254,20 +305,28 @@ template<typename T, int Size, int _Options> class DenseStorage<T, Size, Dynamic
|
||||||
EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0), m_cols(0) {}
|
EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0), m_cols(0) {}
|
||||||
EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
|
EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||||
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {}
|
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {}
|
||||||
EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows), m_cols(other.m_cols) {}
|
EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
|
||||||
|
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(other.m_rows), m_cols(other.m_cols)
|
||||||
|
{
|
||||||
|
internal::plain_array_helper::copy(other.m_data, m_rows * m_cols, m_data);
|
||||||
|
}
|
||||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
||||||
{
|
{
|
||||||
if (this != &other)
|
if (this != &other)
|
||||||
{
|
{
|
||||||
m_data = other.m_data;
|
|
||||||
m_rows = other.m_rows;
|
m_rows = other.m_rows;
|
||||||
m_cols = other.m_cols;
|
m_cols = other.m_cols;
|
||||||
|
internal::plain_array_helper::copy(other.m_data, m_rows * m_cols, m_data);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index cols) : m_rows(rows), m_cols(cols) {}
|
EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index cols) : m_rows(rows), m_cols(cols) {}
|
||||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& other)
|
EIGEN_DEVICE_FUNC void swap(DenseStorage& other)
|
||||||
{ std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
|
{
|
||||||
|
internal::plain_array_helper::swap(m_data, m_rows * m_cols, other.m_data, other.m_rows * other.m_cols);
|
||||||
|
numext::swap(m_rows,other.m_rows);
|
||||||
|
numext::swap(m_cols,other.m_cols);
|
||||||
|
}
|
||||||
EIGEN_DEVICE_FUNC Index rows() const {return m_rows;}
|
EIGEN_DEVICE_FUNC Index rows() const {return m_rows;}
|
||||||
EIGEN_DEVICE_FUNC Index cols() const {return m_cols;}
|
EIGEN_DEVICE_FUNC Index cols() const {return m_cols;}
|
||||||
EIGEN_DEVICE_FUNC void conservativeResize(Index, Index rows, Index cols) { m_rows = rows; m_cols = cols; }
|
EIGEN_DEVICE_FUNC void conservativeResize(Index, Index rows, Index cols) { m_rows = rows; m_cols = cols; }
|
||||||
|
|
@ -285,20 +344,29 @@ template<typename T, int Size, int _Cols, int _Options> class DenseStorage<T, Si
|
||||||
EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0) {}
|
EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0) {}
|
||||||
EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
|
EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||||
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {}
|
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {}
|
||||||
EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows) {}
|
EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
|
||||||
|
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(other.m_rows)
|
||||||
|
{
|
||||||
|
internal::plain_array_helper::copy(other.m_data, m_rows * _Cols, m_data);
|
||||||
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
||||||
{
|
{
|
||||||
if (this != &other)
|
if (this != &other)
|
||||||
{
|
{
|
||||||
m_data = other.m_data;
|
|
||||||
m_rows = other.m_rows;
|
m_rows = other.m_rows;
|
||||||
|
internal::plain_array_helper::copy(other.m_data, m_rows * _Cols, m_data);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index) : m_rows(rows) {}
|
EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index) : m_rows(rows) {}
|
||||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
|
EIGEN_DEVICE_FUNC void swap(DenseStorage& other)
|
||||||
EIGEN_DEVICE_FUNC Index rows(void) const {return m_rows;}
|
{
|
||||||
EIGEN_DEVICE_FUNC Index cols(void) const {return _Cols;}
|
internal::plain_array_helper::swap(m_data, m_rows * _Cols, other.m_data, other.m_rows * _Cols);
|
||||||
|
numext::swap(m_rows, other.m_rows);
|
||||||
|
}
|
||||||
|
EIGEN_DEVICE_FUNC Index rows(void) const EIGEN_NOEXCEPT {return m_rows;}
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols(void) const EIGEN_NOEXCEPT {return _Cols;}
|
||||||
EIGEN_DEVICE_FUNC void conservativeResize(Index, Index rows, Index) { m_rows = rows; }
|
EIGEN_DEVICE_FUNC void conservativeResize(Index, Index rows, Index) { m_rows = rows; }
|
||||||
EIGEN_DEVICE_FUNC void resize(Index, Index rows, Index) { m_rows = rows; }
|
EIGEN_DEVICE_FUNC void resize(Index, Index rows, Index) { m_rows = rows; }
|
||||||
EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
|
EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
|
||||||
|
|
@ -314,22 +382,29 @@ template<typename T, int Size, int _Rows, int _Options> class DenseStorage<T, Si
|
||||||
EIGEN_DEVICE_FUNC DenseStorage() : m_cols(0) {}
|
EIGEN_DEVICE_FUNC DenseStorage() : m_cols(0) {}
|
||||||
EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
|
EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||||
: m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {}
|
: m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {}
|
||||||
EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_cols(other.m_cols) {}
|
EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
|
||||||
|
: m_data(internal::constructor_without_unaligned_array_assert()), m_cols(other.m_cols)
|
||||||
|
{
|
||||||
|
internal::plain_array_helper::copy(other.m_data, _Rows * m_cols, m_data);
|
||||||
|
}
|
||||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
||||||
{
|
{
|
||||||
if (this != &other)
|
if (this != &other)
|
||||||
{
|
{
|
||||||
m_data = other.m_data;
|
|
||||||
m_cols = other.m_cols;
|
m_cols = other.m_cols;
|
||||||
|
internal::plain_array_helper::copy(other.m_data, _Rows * m_cols, m_data);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC DenseStorage(Index, Index, Index cols) : m_cols(cols) {}
|
EIGEN_DEVICE_FUNC DenseStorage(Index, Index, Index cols) : m_cols(cols) {}
|
||||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
|
EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
|
||||||
EIGEN_DEVICE_FUNC Index rows(void) const {return _Rows;}
|
internal::plain_array_helper::swap(m_data, _Rows * m_cols, other.m_data, _Rows * other.m_cols);
|
||||||
EIGEN_DEVICE_FUNC Index cols(void) const {return m_cols;}
|
numext::swap(m_cols, other.m_cols);
|
||||||
void conservativeResize(Index, Index, Index cols) { m_cols = cols; }
|
}
|
||||||
void resize(Index, Index, Index cols) { m_cols = cols; }
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows(void) const EIGEN_NOEXCEPT {return _Rows;}
|
||||||
|
EIGEN_DEVICE_FUNC Index cols(void) const EIGEN_NOEXCEPT {return m_cols;}
|
||||||
|
EIGEN_DEVICE_FUNC void conservativeResize(Index, Index, Index cols) { m_cols = cols; }
|
||||||
|
EIGEN_DEVICE_FUNC void resize(Index, Index, Index cols) { m_cols = cols; }
|
||||||
EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
|
EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
|
||||||
EIGEN_DEVICE_FUNC T *data() { return m_data.array; }
|
EIGEN_DEVICE_FUNC T *data() { return m_data.array; }
|
||||||
};
|
};
|
||||||
|
|
@ -381,18 +456,21 @@ template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynam
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
|
DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
|
||||||
{
|
{
|
||||||
using std::swap;
|
numext::swap(m_data, other.m_data);
|
||||||
swap(m_data, other.m_data);
|
numext::swap(m_rows, other.m_rows);
|
||||||
swap(m_rows, other.m_rows);
|
numext::swap(m_cols, other.m_cols);
|
||||||
swap(m_cols, other.m_cols);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols); }
|
EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols); }
|
||||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& other)
|
EIGEN_DEVICE_FUNC void swap(DenseStorage& other)
|
||||||
{ std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
|
{
|
||||||
EIGEN_DEVICE_FUNC Index rows(void) const {return m_rows;}
|
numext::swap(m_data,other.m_data);
|
||||||
EIGEN_DEVICE_FUNC Index cols(void) const {return m_cols;}
|
numext::swap(m_rows,other.m_rows);
|
||||||
|
numext::swap(m_cols,other.m_cols);
|
||||||
|
}
|
||||||
|
EIGEN_DEVICE_FUNC Index rows(void) const EIGEN_NOEXCEPT {return m_rows;}
|
||||||
|
EIGEN_DEVICE_FUNC Index cols(void) const EIGEN_NOEXCEPT {return m_cols;}
|
||||||
void conservativeResize(Index size, Index rows, Index cols)
|
void conservativeResize(Index size, Index rows, Index cols)
|
||||||
{
|
{
|
||||||
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*m_cols);
|
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*m_cols);
|
||||||
|
|
@ -404,7 +482,7 @@ template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynam
|
||||||
if(size != m_rows*m_cols)
|
if(size != m_rows*m_cols)
|
||||||
{
|
{
|
||||||
internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols);
|
internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols);
|
||||||
if (size)
|
if (size>0) // >0 and not simply !=0 to let the compiler knows that size cannot be negative
|
||||||
m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
|
m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
|
||||||
else
|
else
|
||||||
m_data = 0;
|
m_data = 0;
|
||||||
|
|
@ -459,16 +537,18 @@ template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Ro
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
|
DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
|
||||||
{
|
{
|
||||||
using std::swap;
|
numext::swap(m_data, other.m_data);
|
||||||
swap(m_data, other.m_data);
|
numext::swap(m_cols, other.m_cols);
|
||||||
swap(m_cols, other.m_cols);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); }
|
EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); }
|
||||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
|
EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
|
||||||
EIGEN_DEVICE_FUNC static Index rows(void) {return _Rows;}
|
numext::swap(m_data,other.m_data);
|
||||||
EIGEN_DEVICE_FUNC Index cols(void) const {return m_cols;}
|
numext::swap(m_cols,other.m_cols);
|
||||||
|
}
|
||||||
|
EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index rows(void) EIGEN_NOEXCEPT {return _Rows;}
|
||||||
|
EIGEN_DEVICE_FUNC Index cols(void) const EIGEN_NOEXCEPT {return m_cols;}
|
||||||
EIGEN_DEVICE_FUNC void conservativeResize(Index size, Index, Index cols)
|
EIGEN_DEVICE_FUNC void conservativeResize(Index size, Index, Index cols)
|
||||||
{
|
{
|
||||||
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, _Rows*m_cols);
|
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, _Rows*m_cols);
|
||||||
|
|
@ -479,7 +559,7 @@ template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Ro
|
||||||
if(size != _Rows*m_cols)
|
if(size != _Rows*m_cols)
|
||||||
{
|
{
|
||||||
internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols);
|
internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols);
|
||||||
if (size)
|
if (size>0) // >0 and not simply !=0 to let the compiler knows that size cannot be negative
|
||||||
m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
|
m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
|
||||||
else
|
else
|
||||||
m_data = 0;
|
m_data = 0;
|
||||||
|
|
@ -533,16 +613,18 @@ template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dyn
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
|
DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
|
||||||
{
|
{
|
||||||
using std::swap;
|
numext::swap(m_data, other.m_data);
|
||||||
swap(m_data, other.m_data);
|
numext::swap(m_rows, other.m_rows);
|
||||||
swap(m_rows, other.m_rows);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); }
|
EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); }
|
||||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
|
EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
|
||||||
EIGEN_DEVICE_FUNC Index rows(void) const {return m_rows;}
|
numext::swap(m_data,other.m_data);
|
||||||
EIGEN_DEVICE_FUNC static Index cols(void) {return _Cols;}
|
numext::swap(m_rows,other.m_rows);
|
||||||
|
}
|
||||||
|
EIGEN_DEVICE_FUNC Index rows(void) const EIGEN_NOEXCEPT {return m_rows;}
|
||||||
|
EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index cols(void) {return _Cols;}
|
||||||
void conservativeResize(Index size, Index rows, Index)
|
void conservativeResize(Index size, Index rows, Index)
|
||||||
{
|
{
|
||||||
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*_Cols);
|
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*_Cols);
|
||||||
|
|
@ -553,7 +635,7 @@ template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dyn
|
||||||
if(size != m_rows*_Cols)
|
if(size != m_rows*_Cols)
|
||||||
{
|
{
|
||||||
internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows);
|
internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows);
|
||||||
if (size)
|
if (size>0) // >0 and not simply !=0 to let the compiler knows that size cannot be negative
|
||||||
m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
|
m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
|
||||||
else
|
else
|
||||||
m_data = 0;
|
m_data = 0;
|
||||||
|
|
|
||||||
|
|
@ -84,20 +84,16 @@ template<typename MatrixType, int _DiagIndex> class Diagonal
|
||||||
: numext::mini<Index>(m_matrix.rows(),m_matrix.cols()-m_index.value());
|
: numext::mini<Index>(m_matrix.rows(),m_matrix.cols()-m_index.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index cols() const { return 1; }
|
inline Index cols() const EIGEN_NOEXCEPT { return 1; }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index innerStride() const
|
inline Index innerStride() const EIGEN_NOEXCEPT {
|
||||||
{
|
|
||||||
return m_matrix.outerStride() + 1;
|
return m_matrix.outerStride() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index outerStride() const
|
inline Index outerStride() const EIGEN_NOEXCEPT { return 0; }
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef typename internal::conditional<
|
typedef typename internal::conditional<
|
||||||
internal::is_lvalue<MatrixType>::value,
|
internal::is_lvalue<MatrixType>::value,
|
||||||
|
|
@ -167,12 +163,12 @@ template<typename MatrixType, int _DiagIndex> class Diagonal
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// some compilers may fail to optimize std::max etc in case of compile-time constants...
|
// some compilers may fail to optimize std::max etc in case of compile-time constants...
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
EIGEN_STRONG_INLINE Index absDiagIndex() const { return m_index.value()>0 ? m_index.value() : -m_index.value(); }
|
Index absDiagIndex() const EIGEN_NOEXCEPT { return m_index.value()>0 ? m_index.value() : -m_index.value(); }
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
EIGEN_STRONG_INLINE Index rowOffset() const { return m_index.value()>0 ? 0 : -m_index.value(); }
|
Index rowOffset() const EIGEN_NOEXCEPT { return m_index.value()>0 ? 0 : -m_index.value(); }
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
EIGEN_STRONG_INLINE Index colOffset() const { return m_index.value()>0 ? m_index.value() : 0; }
|
Index colOffset() const EIGEN_NOEXCEPT { return m_index.value()>0 ? m_index.value() : 0; }
|
||||||
// trigger a compile-time error if someone try to call packet
|
// trigger a compile-time error if someone try to call packet
|
||||||
template<int LoadMode> typename MatrixType::PacketReturnType packet(Index) const;
|
template<int LoadMode> typename MatrixType::PacketReturnType packet(Index) const;
|
||||||
template<int LoadMode> typename MatrixType::PacketReturnType packet(Index,Index) const;
|
template<int LoadMode> typename MatrixType::PacketReturnType packet(Index,Index) const;
|
||||||
|
|
@ -187,7 +183,7 @@ template<typename MatrixType, int _DiagIndex> class Diagonal
|
||||||
*
|
*
|
||||||
* \sa class Diagonal */
|
* \sa class Diagonal */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline typename MatrixBase<Derived>::DiagonalReturnType
|
EIGEN_DEVICE_FUNC inline typename MatrixBase<Derived>::DiagonalReturnType
|
||||||
MatrixBase<Derived>::diagonal()
|
MatrixBase<Derived>::diagonal()
|
||||||
{
|
{
|
||||||
return DiagonalReturnType(derived());
|
return DiagonalReturnType(derived());
|
||||||
|
|
@ -195,7 +191,7 @@ MatrixBase<Derived>::diagonal()
|
||||||
|
|
||||||
/** This is the const version of diagonal(). */
|
/** This is the const version of diagonal(). */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline typename MatrixBase<Derived>::ConstDiagonalReturnType
|
EIGEN_DEVICE_FUNC inline typename MatrixBase<Derived>::ConstDiagonalReturnType
|
||||||
MatrixBase<Derived>::diagonal() const
|
MatrixBase<Derived>::diagonal() const
|
||||||
{
|
{
|
||||||
return ConstDiagonalReturnType(derived());
|
return ConstDiagonalReturnType(derived());
|
||||||
|
|
@ -213,7 +209,7 @@ MatrixBase<Derived>::diagonal() const
|
||||||
*
|
*
|
||||||
* \sa MatrixBase::diagonal(), class Diagonal */
|
* \sa MatrixBase::diagonal(), class Diagonal */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline typename MatrixBase<Derived>::DiagonalDynamicIndexReturnType
|
EIGEN_DEVICE_FUNC inline typename MatrixBase<Derived>::DiagonalDynamicIndexReturnType
|
||||||
MatrixBase<Derived>::diagonal(Index index)
|
MatrixBase<Derived>::diagonal(Index index)
|
||||||
{
|
{
|
||||||
return DiagonalDynamicIndexReturnType(derived(), index);
|
return DiagonalDynamicIndexReturnType(derived(), index);
|
||||||
|
|
@ -221,7 +217,7 @@ MatrixBase<Derived>::diagonal(Index index)
|
||||||
|
|
||||||
/** This is the const version of diagonal(Index). */
|
/** This is the const version of diagonal(Index). */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline typename MatrixBase<Derived>::ConstDiagonalDynamicIndexReturnType
|
EIGEN_DEVICE_FUNC inline typename MatrixBase<Derived>::ConstDiagonalDynamicIndexReturnType
|
||||||
MatrixBase<Derived>::diagonal(Index index) const
|
MatrixBase<Derived>::diagonal(Index index) const
|
||||||
{
|
{
|
||||||
return ConstDiagonalDynamicIndexReturnType(derived(), index);
|
return ConstDiagonalDynamicIndexReturnType(derived(), index);
|
||||||
|
|
@ -240,6 +236,7 @@ MatrixBase<Derived>::diagonal(Index index) const
|
||||||
* \sa MatrixBase::diagonal(), class Diagonal */
|
* \sa MatrixBase::diagonal(), class Diagonal */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<int Index_>
|
template<int Index_>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
inline typename MatrixBase<Derived>::template DiagonalIndexReturnType<Index_>::Type
|
inline typename MatrixBase<Derived>::template DiagonalIndexReturnType<Index_>::Type
|
||||||
MatrixBase<Derived>::diagonal()
|
MatrixBase<Derived>::diagonal()
|
||||||
{
|
{
|
||||||
|
|
@ -249,6 +246,7 @@ MatrixBase<Derived>::diagonal()
|
||||||
/** 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
|
||||||
inline typename MatrixBase<Derived>::template ConstDiagonalIndexReturnType<Index_>::Type
|
inline typename MatrixBase<Derived>::template ConstDiagonalIndexReturnType<Index_>::Type
|
||||||
MatrixBase<Derived>::diagonal() const
|
MatrixBase<Derived>::diagonal() const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,30 @@ class DiagonalBase : public EigenBase<Derived>
|
||||||
{
|
{
|
||||||
return DiagonalWrapper<const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar,DiagonalVectorType,product) >(scalar * other.diagonal());
|
return DiagonalWrapper<const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar,DiagonalVectorType,product) >(scalar * other.diagonal());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename OtherDerived>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
inline unspecified_expression_type
|
||||||
|
#else
|
||||||
|
inline const DiagonalWrapper<const EIGEN_CWISE_BINARY_RETURN_TYPE(DiagonalVectorType,typename OtherDerived::DiagonalVectorType,sum) >
|
||||||
|
#endif
|
||||||
|
operator+(const DiagonalBase<OtherDerived>& other) const
|
||||||
|
{
|
||||||
|
return (diagonal() + other.diagonal()).asDiagonal();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename OtherDerived>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
inline unspecified_expression_type
|
||||||
|
#else
|
||||||
|
inline const DiagonalWrapper<const EIGEN_CWISE_BINARY_RETURN_TYPE(DiagonalVectorType,typename OtherDerived::DiagonalVectorType,difference) >
|
||||||
|
#endif
|
||||||
|
operator-(const DiagonalBase<OtherDerived>& other) const
|
||||||
|
{
|
||||||
|
return (diagonal() - other.diagonal()).asDiagonal();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -154,6 +178,30 @@ class DiagonalMatrix
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline DiagonalMatrix(const Scalar& x, const Scalar& y, const Scalar& z) : m_diagonal(x,y,z) {}
|
inline DiagonalMatrix(const Scalar& x, const Scalar& y, const Scalar& z) : m_diagonal(x,y,z) {}
|
||||||
|
|
||||||
|
#if EIGEN_HAS_CXX11
|
||||||
|
/** \brief Construct a diagonal matrix with fixed size from an arbitrary number of coefficients. \cpp11
|
||||||
|
*
|
||||||
|
* There exists C++98 anologue constructors for fixed-size diagonal matrices having 2 or 3 coefficients.
|
||||||
|
*
|
||||||
|
* \warning To construct a diagonal matrix of fixed size, the number of values passed to this
|
||||||
|
* constructor must match the fixed dimension of \c *this.
|
||||||
|
*
|
||||||
|
* \sa DiagonalMatrix(const Scalar&, const Scalar&)
|
||||||
|
* \sa DiagonalMatrix(const Scalar&, const Scalar&, const Scalar&)
|
||||||
|
*/
|
||||||
|
template <typename... ArgTypes>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
DiagonalMatrix(const Scalar& a0, const Scalar& a1, const Scalar& a2, const ArgTypes&... args)
|
||||||
|
: m_diagonal(a0, a1, a2, args...) {}
|
||||||
|
|
||||||
|
/** \brief Constructs a DiagonalMatrix and initializes it by elements given by an initializer list of initializer
|
||||||
|
* lists \cpp11
|
||||||
|
*/
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
explicit EIGEN_STRONG_INLINE DiagonalMatrix(const std::initializer_list<std::initializer_list<Scalar>>& list)
|
||||||
|
: m_diagonal(list) {}
|
||||||
|
#endif // EIGEN_HAS_CXX11
|
||||||
|
|
||||||
/** Copy constructor. */
|
/** Copy constructor. */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
|
|
@ -273,7 +321,7 @@ class DiagonalWrapper
|
||||||
* \sa class DiagonalWrapper, class DiagonalMatrix, diagonal(), isDiagonal()
|
* \sa class DiagonalWrapper, class DiagonalMatrix, diagonal(), isDiagonal()
|
||||||
**/
|
**/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline const DiagonalWrapper<const Derived>
|
EIGEN_DEVICE_FUNC inline const DiagonalWrapper<const Derived>
|
||||||
MatrixBase<Derived>::asDiagonal() const
|
MatrixBase<Derived>::asDiagonal() const
|
||||||
{
|
{
|
||||||
return DiagonalWrapper<const Derived>(derived());
|
return DiagonalWrapper<const Derived>(derived());
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ namespace Eigen {
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename DiagonalDerived>
|
template<typename DiagonalDerived>
|
||||||
inline const Product<Derived, DiagonalDerived, LazyProduct>
|
EIGEN_DEVICE_FUNC inline const Product<Derived, DiagonalDerived, LazyProduct>
|
||||||
MatrixBase<Derived>::operator*(const DiagonalBase<DiagonalDerived> &a_diagonal) const
|
MatrixBase<Derived>::operator*(const DiagonalBase<DiagonalDerived> &a_diagonal) const
|
||||||
{
|
{
|
||||||
return Product<Derived, DiagonalDerived, LazyProduct>(derived(),a_diagonal.derived());
|
return Product<Derived, DiagonalDerived, LazyProduct>(derived(),a_diagonal.derived());
|
||||||
|
|
|
||||||
|
|
@ -86,14 +86,14 @@ MatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const
|
||||||
|
|
||||||
//---------- 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 Frobenius norm.
|
/** \returns, for vectors, the squared \em l2 norm of \c *this, and for matrices the squared 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 equals 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(), lpNorm()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::squaredNorm() const
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::squaredNorm() const
|
||||||
{
|
{
|
||||||
return numext::real((*this).cwiseAbs2().sum());
|
return numext::real((*this).cwiseAbs2().sum());
|
||||||
}
|
}
|
||||||
|
|
@ -105,7 +105,7 @@ EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scala
|
||||||
* \sa lpNorm(), dot(), squaredNorm()
|
* \sa lpNorm(), dot(), squaredNorm()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::norm() const
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::norm() const
|
||||||
{
|
{
|
||||||
return numext::sqrt(squaredNorm());
|
return numext::sqrt(squaredNorm());
|
||||||
}
|
}
|
||||||
|
|
@ -120,7 +120,7 @@ EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scala
|
||||||
* \sa norm(), normalize()
|
* \sa norm(), normalize()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::PlainObject
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::PlainObject
|
||||||
MatrixBase<Derived>::normalized() const
|
MatrixBase<Derived>::normalized() const
|
||||||
{
|
{
|
||||||
typedef typename internal::nested_eval<Derived,2>::type _Nested;
|
typedef typename internal::nested_eval<Derived,2>::type _Nested;
|
||||||
|
|
@ -142,7 +142,7 @@ MatrixBase<Derived>::normalized() const
|
||||||
* \sa norm(), normalized()
|
* \sa norm(), normalized()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_STRONG_INLINE void MatrixBase<Derived>::normalize()
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void MatrixBase<Derived>::normalize()
|
||||||
{
|
{
|
||||||
RealScalar z = squaredNorm();
|
RealScalar z = squaredNorm();
|
||||||
// NOTE: after extensive benchmarking, this conditional does not impact performance, at least on recent x86 CPU
|
// NOTE: after extensive benchmarking, this conditional does not impact performance, at least on recent x86 CPU
|
||||||
|
|
@ -163,7 +163,7 @@ EIGEN_STRONG_INLINE void MatrixBase<Derived>::normalize()
|
||||||
* \sa stableNorm(), stableNormalize(), normalized()
|
* \sa stableNorm(), stableNormalize(), normalized()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::PlainObject
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::PlainObject
|
||||||
MatrixBase<Derived>::stableNormalized() const
|
MatrixBase<Derived>::stableNormalized() const
|
||||||
{
|
{
|
||||||
typedef typename internal::nested_eval<Derived,3>::type _Nested;
|
typedef typename internal::nested_eval<Derived,3>::type _Nested;
|
||||||
|
|
@ -188,7 +188,7 @@ MatrixBase<Derived>::stableNormalized() const
|
||||||
* \sa stableNorm(), stableNormalized(), normalize()
|
* \sa stableNorm(), stableNormalized(), normalize()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_STRONG_INLINE void MatrixBase<Derived>::stableNormalize()
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void MatrixBase<Derived>::stableNormalize()
|
||||||
{
|
{
|
||||||
RealScalar w = cwiseAbs().maxCoeff();
|
RealScalar w = cwiseAbs().maxCoeff();
|
||||||
RealScalar z = (derived()/w).squaredNorm();
|
RealScalar z = (derived()/w).squaredNorm();
|
||||||
|
|
@ -207,7 +207,7 @@ struct lpNorm_selector
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
static inline RealScalar run(const MatrixBase<Derived>& m)
|
static inline RealScalar run(const MatrixBase<Derived>& m)
|
||||||
{
|
{
|
||||||
EIGEN_USING_STD_MATH(pow)
|
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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -260,9 +260,9 @@ struct lpNorm_selector<Derived, Infinity>
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<int p>
|
template<int p>
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#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
|
||||||
#else
|
#else
|
||||||
MatrixBase<Derived>::RealScalar
|
EIGEN_DEVICE_FUNC MatrixBase<Derived>::RealScalar
|
||||||
#endif
|
#endif
|
||||||
MatrixBase<Derived>::lpNorm() const
|
MatrixBase<Derived>::lpNorm() const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,9 @@ template<typename Derived> struct EigenBase
|
||||||
|
|
||||||
/** \brief The interface type of indices
|
/** \brief The interface type of indices
|
||||||
* \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE.
|
* \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE.
|
||||||
* \deprecated Since Eigen 3.3, its usage is deprecated. Use Eigen::Index instead.
|
|
||||||
* \sa StorageIndex, \ref TopicPreprocessorDirectives.
|
* \sa StorageIndex, \ref TopicPreprocessorDirectives.
|
||||||
|
* DEPRECATED: Since Eigen 3.3, its usage is deprecated. Use Eigen::Index instead.
|
||||||
|
* Deprecation is not marked with a doxygen comment because there are too many existing usages to add the deprecation attribute.
|
||||||
*/
|
*/
|
||||||
typedef Eigen::Index Index;
|
typedef Eigen::Index Index;
|
||||||
|
|
||||||
|
|
@ -55,15 +56,15 @@ template<typename Derived> struct EigenBase
|
||||||
{ return *static_cast<const Derived*>(this); }
|
{ return *static_cast<const Derived*>(this); }
|
||||||
|
|
||||||
/** \returns the number of rows. \sa cols(), RowsAtCompileTime */
|
/** \returns the number of rows. \sa cols(), RowsAtCompileTime */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index rows() const { return derived().rows(); }
|
inline Index rows() const EIGEN_NOEXCEPT { return derived().rows(); }
|
||||||
/** \returns the number of columns. \sa rows(), ColsAtCompileTime*/
|
/** \returns the number of columns. \sa rows(), ColsAtCompileTime*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index cols() const { return derived().cols(); }
|
inline Index cols() const EIGEN_NOEXCEPT { return derived().cols(); }
|
||||||
/** \returns the number of coefficients, which is rows()*cols().
|
/** \returns the number of coefficients, which is rows()*cols().
|
||||||
* \sa rows(), cols(), SizeAtCompileTime. */
|
* \sa rows(), cols(), SizeAtCompileTime. */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index size() const { return rows() * cols(); }
|
inline Index size() const EIGEN_NOEXCEPT { return rows() * cols(); }
|
||||||
|
|
||||||
/** \internal Don't use it, but do the equivalent: \code dst = *this; \endcode */
|
/** \internal Don't use it, but do the equivalent: \code dst = *this; \endcode */
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
|
|
|
||||||
|
|
@ -41,10 +41,14 @@ template<typename ExpressionType> class ForceAlignedAccess
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit inline ForceAlignedAccess(const ExpressionType& matrix) : m_expression(matrix) {}
|
EIGEN_DEVICE_FUNC explicit inline ForceAlignedAccess(const ExpressionType& matrix) : m_expression(matrix) {}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline Index rows() const { return m_expression.rows(); }
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
EIGEN_DEVICE_FUNC inline Index cols() const { return m_expression.cols(); }
|
inline Index rows() const EIGEN_NOEXCEPT { return m_expression.rows(); }
|
||||||
EIGEN_DEVICE_FUNC inline Index outerStride() const { return m_expression.outerStride(); }
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
EIGEN_DEVICE_FUNC inline Index innerStride() const { return m_expression.innerStride(); }
|
inline Index cols() const EIGEN_NOEXCEPT { return m_expression.cols(); }
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
|
inline Index outerStride() const EIGEN_NOEXCEPT { return m_expression.outerStride(); }
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
|
inline Index innerStride() const EIGEN_NOEXCEPT { return m_expression.innerStride(); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline const CoeffReturnType coeff(Index row, Index col) const
|
EIGEN_DEVICE_FUNC inline const CoeffReturnType coeff(Index row, Index col) const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ struct isMuchSmallerThan_scalar_selector<Derived, true>
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
bool DenseBase<Derived>::isApprox(
|
EIGEN_DEVICE_FUNC bool DenseBase<Derived>::isApprox(
|
||||||
const DenseBase<OtherDerived>& other,
|
const DenseBase<OtherDerived>& other,
|
||||||
const RealScalar& prec
|
const RealScalar& prec
|
||||||
) const
|
) const
|
||||||
|
|
@ -122,7 +122,7 @@ bool DenseBase<Derived>::isApprox(
|
||||||
* \sa isApprox(), isMuchSmallerThan(const DenseBase<OtherDerived>&, RealScalar) const
|
* \sa isApprox(), isMuchSmallerThan(const DenseBase<OtherDerived>&, RealScalar) const
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
bool DenseBase<Derived>::isMuchSmallerThan(
|
EIGEN_DEVICE_FUNC bool DenseBase<Derived>::isMuchSmallerThan(
|
||||||
const typename NumTraits<Scalar>::Real& other,
|
const typename NumTraits<Scalar>::Real& other,
|
||||||
const RealScalar& prec
|
const RealScalar& prec
|
||||||
) const
|
) const
|
||||||
|
|
@ -142,7 +142,7 @@ bool DenseBase<Derived>::isMuchSmallerThan(
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
bool DenseBase<Derived>::isMuchSmallerThan(
|
EIGEN_DEVICE_FUNC bool DenseBase<Derived>::isMuchSmallerThan(
|
||||||
const DenseBase<OtherDerived>& other,
|
const DenseBase<OtherDerived>& other,
|
||||||
const RealScalar& prec
|
const RealScalar& prec
|
||||||
) const
|
) const
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,16 @@ enum {
|
||||||
Small = 3
|
Small = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Define the threshold value to fallback from the generic matrix-matrix product
|
||||||
|
// implementation (heavy) to the lightweight coeff-based product one.
|
||||||
|
// See generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,GemmProduct>
|
||||||
|
// in products/GeneralMatrixMatrix.h for more details.
|
||||||
|
// TODO This threshold should also be used in the compile-time selector below.
|
||||||
|
#ifndef EIGEN_GEMM_TO_COEFFBASED_THRESHOLD
|
||||||
|
// This default value has been obtained on a Haswell architecture.
|
||||||
|
#define EIGEN_GEMM_TO_COEFFBASED_THRESHOLD 20
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template<int Rows, int Cols, int Depth> struct product_type_selector;
|
template<int Rows, int Cols, int Depth> struct product_type_selector;
|
||||||
|
|
@ -25,7 +35,7 @@ template<int Rows, int Cols, int Depth> struct product_type_selector;
|
||||||
template<int Size, int MaxSize> struct product_size_category
|
template<int Size, int MaxSize> struct product_size_category
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
#ifndef EIGEN_CUDA_ARCH
|
#ifndef EIGEN_GPU_COMPILE_PHASE
|
||||||
is_large = MaxSize == Dynamic ||
|
is_large = MaxSize == Dynamic ||
|
||||||
Size >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD ||
|
Size >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD ||
|
||||||
(Size==Dynamic && MaxSize>=EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD),
|
(Size==Dynamic && MaxSize>=EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD),
|
||||||
|
|
@ -153,13 +163,13 @@ template<typename Scalar,int Size,int MaxSize,bool Cond> struct gemv_static_vect
|
||||||
template<typename Scalar,int Size,int MaxSize>
|
template<typename Scalar,int Size,int MaxSize>
|
||||||
struct gemv_static_vector_if<Scalar,Size,MaxSize,false>
|
struct gemv_static_vector_if<Scalar,Size,MaxSize,false>
|
||||||
{
|
{
|
||||||
EIGEN_STRONG_INLINE Scalar* data() { eigen_internal_assert(false && "should never be called"); return 0; }
|
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Scalar* data() { eigen_internal_assert(false && "should never be called"); return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Scalar,int Size>
|
template<typename Scalar,int Size>
|
||||||
struct gemv_static_vector_if<Scalar,Size,Dynamic,true>
|
struct gemv_static_vector_if<Scalar,Size,Dynamic,true>
|
||||||
{
|
{
|
||||||
EIGEN_STRONG_INLINE Scalar* data() { return 0; }
|
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Scalar* data() { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Scalar,int Size,int MaxSize>
|
template<typename Scalar,int Size,int MaxSize>
|
||||||
|
|
@ -218,8 +228,7 @@ template<> struct gemv_dense_selector<OnTheRight,ColMajor,true>
|
||||||
ActualLhsType actualLhs = LhsBlasTraits::extract(lhs);
|
ActualLhsType actualLhs = LhsBlasTraits::extract(lhs);
|
||||||
ActualRhsType actualRhs = RhsBlasTraits::extract(rhs);
|
ActualRhsType actualRhs = RhsBlasTraits::extract(rhs);
|
||||||
|
|
||||||
ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(lhs)
|
ResScalar actualAlpha = combine_scalar_factors(alpha, lhs, rhs);
|
||||||
* RhsBlasTraits::extractScalarFactor(rhs);
|
|
||||||
|
|
||||||
// make sure Dest is a compile-time vector type (bug 1166)
|
// make sure Dest is a compile-time vector type (bug 1166)
|
||||||
typedef typename conditional<Dest::IsVectorAtCompileTime, Dest, typename Dest::ColXpr>::type ActualDest;
|
typedef typename conditional<Dest::IsVectorAtCompileTime, Dest, typename Dest::ColXpr>::type ActualDest;
|
||||||
|
|
@ -229,7 +238,7 @@ template<> struct gemv_dense_selector<OnTheRight,ColMajor,true>
|
||||||
// on, the other hand it is good for the cache to pack the vector anyways...
|
// on, the other hand it is good for the cache to pack the vector anyways...
|
||||||
EvalToDestAtCompileTime = (ActualDest::InnerStrideAtCompileTime==1),
|
EvalToDestAtCompileTime = (ActualDest::InnerStrideAtCompileTime==1),
|
||||||
ComplexByReal = (NumTraits<LhsScalar>::IsComplex) && (!NumTraits<RhsScalar>::IsComplex),
|
ComplexByReal = (NumTraits<LhsScalar>::IsComplex) && (!NumTraits<RhsScalar>::IsComplex),
|
||||||
MightCannotUseDest = (!EvalToDestAtCompileTime) || ComplexByReal
|
MightCannotUseDest = ((!EvalToDestAtCompileTime) || ComplexByReal) && (ActualDest::MaxSizeAtCompileTime!=0)
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef const_blas_data_mapper<LhsScalar,Index,ColMajor> LhsMapper;
|
typedef const_blas_data_mapper<LhsScalar,Index,ColMajor> LhsMapper;
|
||||||
|
|
@ -310,13 +319,12 @@ template<> struct gemv_dense_selector<OnTheRight,RowMajor,true>
|
||||||
typename add_const<ActualLhsType>::type actualLhs = LhsBlasTraits::extract(lhs);
|
typename add_const<ActualLhsType>::type actualLhs = LhsBlasTraits::extract(lhs);
|
||||||
typename add_const<ActualRhsType>::type actualRhs = RhsBlasTraits::extract(rhs);
|
typename add_const<ActualRhsType>::type actualRhs = RhsBlasTraits::extract(rhs);
|
||||||
|
|
||||||
ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(lhs)
|
ResScalar actualAlpha = combine_scalar_factors(alpha, lhs, rhs);
|
||||||
* RhsBlasTraits::extractScalarFactor(rhs);
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
// FIXME find a way to allow an inner stride on the result if packet_traits<Scalar>::size==1
|
// FIXME find a way to allow an inner stride on the result if packet_traits<Scalar>::size==1
|
||||||
// on, the other hand it is good for the cache to pack the vector anyways...
|
// on, the other hand it is good for the cache to pack the vector anyways...
|
||||||
DirectlyUseRhs = ActualRhsTypeCleaned::InnerStrideAtCompileTime==1
|
DirectlyUseRhs = ActualRhsTypeCleaned::InnerStrideAtCompileTime==1 || ActualRhsTypeCleaned::MaxSizeAtCompileTime==0
|
||||||
};
|
};
|
||||||
|
|
||||||
gemv_static_vector_if<RhsScalar,ActualRhsTypeCleaned::SizeAtCompileTime,ActualRhsTypeCleaned::MaxSizeAtCompileTime,!DirectlyUseRhs> static_rhs;
|
gemv_static_vector_if<RhsScalar,ActualRhsTypeCleaned::SizeAtCompileTime,ActualRhsTypeCleaned::MaxSizeAtCompileTime,!DirectlyUseRhs> static_rhs;
|
||||||
|
|
@ -386,7 +394,8 @@ template<> struct gemv_dense_selector<OnTheRight,RowMajor,false>
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
inline const Product<Derived, OtherDerived>
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
const Product<Derived, OtherDerived>
|
||||||
MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
|
MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
|
||||||
{
|
{
|
||||||
// A note regarding the function declaration: In MSVC, this function will sometimes
|
// A note regarding the function declaration: In MSVC, this function will sometimes
|
||||||
|
|
@ -428,6 +437,7 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
const Product<Derived,OtherDerived,LazyProduct>
|
const Product<Derived,OtherDerived,LazyProduct>
|
||||||
MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &other) const
|
MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &other) const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -46,21 +46,27 @@ struct default_packet_traits
|
||||||
|
|
||||||
HasAdd = 1,
|
HasAdd = 1,
|
||||||
HasSub = 1,
|
HasSub = 1,
|
||||||
|
HasShift = 1,
|
||||||
HasMul = 1,
|
HasMul = 1,
|
||||||
HasNegate = 1,
|
HasNegate = 1,
|
||||||
HasAbs = 1,
|
HasAbs = 1,
|
||||||
HasArg = 0,
|
HasArg = 0,
|
||||||
HasAbs2 = 1,
|
HasAbs2 = 1,
|
||||||
|
HasAbsDiff = 0,
|
||||||
HasMin = 1,
|
HasMin = 1,
|
||||||
HasMax = 1,
|
HasMax = 1,
|
||||||
HasConj = 1,
|
HasConj = 1,
|
||||||
HasSetLinear = 1,
|
HasSetLinear = 1,
|
||||||
HasBlend = 0,
|
HasBlend = 0,
|
||||||
|
// This flag is used to indicate whether packet comparison is supported.
|
||||||
|
// pcmp_eq, pcmp_lt and pcmp_le should be defined for it to be true.
|
||||||
|
HasCmp = 0,
|
||||||
|
|
||||||
HasDiv = 0,
|
HasDiv = 0,
|
||||||
HasSqrt = 0,
|
HasSqrt = 0,
|
||||||
HasRsqrt = 0,
|
HasRsqrt = 0,
|
||||||
HasExp = 0,
|
HasExp = 0,
|
||||||
|
HasExpm1 = 0,
|
||||||
HasLog = 0,
|
HasLog = 0,
|
||||||
HasLog1p = 0,
|
HasLog1p = 0,
|
||||||
HasLog10 = 0,
|
HasLog10 = 0,
|
||||||
|
|
@ -81,14 +87,18 @@ struct default_packet_traits
|
||||||
HasPolygamma = 0,
|
HasPolygamma = 0,
|
||||||
HasErf = 0,
|
HasErf = 0,
|
||||||
HasErfc = 0,
|
HasErfc = 0,
|
||||||
|
HasNdtri = 0,
|
||||||
|
HasBessel = 0,
|
||||||
HasIGamma = 0,
|
HasIGamma = 0,
|
||||||
|
HasIGammaDerA = 0,
|
||||||
|
HasGammaSampleDerAlpha = 0,
|
||||||
HasIGammac = 0,
|
HasIGammac = 0,
|
||||||
HasBetaInc = 0,
|
HasBetaInc = 0,
|
||||||
|
|
||||||
HasRound = 0,
|
HasRound = 0,
|
||||||
|
HasRint = 0,
|
||||||
HasFloor = 0,
|
HasFloor = 0,
|
||||||
HasCeil = 0,
|
HasCeil = 0,
|
||||||
|
|
||||||
HasSign = 0
|
HasSign = 0
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -119,6 +129,22 @@ template<typename T> struct packet_traits : default_packet_traits
|
||||||
|
|
||||||
template<typename T> struct packet_traits<const T> : packet_traits<T> { };
|
template<typename T> struct packet_traits<const T> : packet_traits<T> { };
|
||||||
|
|
||||||
|
template<typename T> struct unpacket_traits
|
||||||
|
{
|
||||||
|
typedef T type;
|
||||||
|
typedef T half;
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
size = 1,
|
||||||
|
alignment = 1,
|
||||||
|
vectorizable = false,
|
||||||
|
masked_load_available=false,
|
||||||
|
masked_store_available=false
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T> struct unpacket_traits<const T> : unpacket_traits<T> { };
|
||||||
|
|
||||||
template <typename Src, typename Tgt> struct type_casting_traits {
|
template <typename Src, typename Tgt> struct type_casting_traits {
|
||||||
enum {
|
enum {
|
||||||
VectorizedCast = 0,
|
VectorizedCast = 0,
|
||||||
|
|
@ -127,6 +153,34 @@ template <typename Src, typename Tgt> struct type_casting_traits {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** \internal Wrapper to ensure that multiple packet types can map to the same
|
||||||
|
same underlying vector type. */
|
||||||
|
template<typename T, int unique_id = 0>
|
||||||
|
struct eigen_packet_wrapper
|
||||||
|
{
|
||||||
|
EIGEN_ALWAYS_INLINE operator T&() { return m_val; }
|
||||||
|
EIGEN_ALWAYS_INLINE operator const T&() const { return m_val; }
|
||||||
|
EIGEN_ALWAYS_INLINE eigen_packet_wrapper() {}
|
||||||
|
EIGEN_ALWAYS_INLINE eigen_packet_wrapper(const T &v) : m_val(v) {}
|
||||||
|
EIGEN_ALWAYS_INLINE eigen_packet_wrapper& operator=(const T &v) {
|
||||||
|
m_val = v;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
T m_val;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** \internal A convenience utility for determining if the type is a scalar.
|
||||||
|
* This is used to enable some generic packet implementations.
|
||||||
|
*/
|
||||||
|
template<typename Packet>
|
||||||
|
struct is_scalar {
|
||||||
|
typedef typename unpacket_traits<Packet>::type Scalar;
|
||||||
|
enum {
|
||||||
|
value = internal::is_same<Packet, Scalar>::value
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
/** \internal \returns static_cast<TgtType>(a) (coeff-wise) */
|
/** \internal \returns static_cast<TgtType>(a) (coeff-wise) */
|
||||||
template <typename SrcPacket, typename TgtPacket>
|
template <typename SrcPacket, typename TgtPacket>
|
||||||
|
|
@ -139,75 +193,406 @@ EIGEN_DEVICE_FUNC inline TgtPacket
|
||||||
pcast(const SrcPacket& a, const SrcPacket& /*b*/) {
|
pcast(const SrcPacket& a, const SrcPacket& /*b*/) {
|
||||||
return static_cast<TgtPacket>(a);
|
return static_cast<TgtPacket>(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename SrcPacket, typename TgtPacket>
|
template <typename SrcPacket, typename TgtPacket>
|
||||||
EIGEN_DEVICE_FUNC inline TgtPacket
|
EIGEN_DEVICE_FUNC inline TgtPacket
|
||||||
pcast(const SrcPacket& a, const SrcPacket& /*b*/, const SrcPacket& /*c*/, const SrcPacket& /*d*/) {
|
pcast(const SrcPacket& a, const SrcPacket& /*b*/, const SrcPacket& /*c*/, const SrcPacket& /*d*/) {
|
||||||
return static_cast<TgtPacket>(a);
|
return static_cast<TgtPacket>(a);
|
||||||
}
|
}
|
||||||
|
template <typename SrcPacket, typename TgtPacket>
|
||||||
|
EIGEN_DEVICE_FUNC inline TgtPacket
|
||||||
|
pcast(const SrcPacket& a, const SrcPacket& /*b*/, const SrcPacket& /*c*/, const SrcPacket& /*d*/,
|
||||||
|
const SrcPacket& /*e*/, const SrcPacket& /*f*/, const SrcPacket& /*g*/, const SrcPacket& /*h*/) {
|
||||||
|
return static_cast<TgtPacket>(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \internal \returns reinterpret_cast<Target>(a) */
|
||||||
|
template <typename Target, typename Packet>
|
||||||
|
EIGEN_DEVICE_FUNC inline Target
|
||||||
|
preinterpret(const Packet& a); /* { return reinterpret_cast<const Target&>(a); } */
|
||||||
|
|
||||||
/** \internal \returns a + b (coeff-wise) */
|
/** \internal \returns a + b (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
padd(const Packet& a,
|
padd(const Packet& a, const Packet& b) { return a+b; }
|
||||||
const Packet& b) { return a+b; }
|
// Avoid compiler warning for boolean algebra.
|
||||||
|
template<> EIGEN_DEVICE_FUNC inline bool
|
||||||
|
padd(const bool& a, const bool& b) { return a || b; }
|
||||||
|
|
||||||
/** \internal \returns a - b (coeff-wise) */
|
/** \internal \returns a - b (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
psub(const Packet& a,
|
psub(const Packet& a, const Packet& b) { return a-b; }
|
||||||
const Packet& b) { return a-b; }
|
|
||||||
|
|
||||||
/** \internal \returns -a (coeff-wise) */
|
/** \internal \returns -a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
pnegate(const Packet& a) { return -a; }
|
pnegate(const Packet& a) { return -a; }
|
||||||
|
|
||||||
/** \internal \returns conj(a) (coeff-wise) */
|
template<> EIGEN_DEVICE_FUNC inline bool
|
||||||
|
pnegate(const bool& a) { return !a; }
|
||||||
|
|
||||||
|
/** \internal \returns conj(a) (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
pconj(const Packet& a) { return numext::conj(a); }
|
pconj(const Packet& a) { return numext::conj(a); }
|
||||||
|
|
||||||
/** \internal \returns a * b (coeff-wise) */
|
/** \internal \returns a * b (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
pmul(const Packet& a,
|
pmul(const Packet& a, const Packet& b) { return a*b; }
|
||||||
const Packet& b) { return a*b; }
|
// Avoid compiler warning for boolean algebra.
|
||||||
|
template<> EIGEN_DEVICE_FUNC inline bool
|
||||||
|
pmul(const bool& a, const bool& b) { return a && b; }
|
||||||
|
|
||||||
/** \internal \returns a / b (coeff-wise) */
|
/** \internal \returns a / b (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
pdiv(const Packet& a,
|
pdiv(const Packet& a, const Packet& b) { return a/b; }
|
||||||
const Packet& b) { return a/b; }
|
|
||||||
|
|
||||||
/** \internal \returns the min of \a a and \a b (coeff-wise) */
|
// In the generic case, memset to all one bits.
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet, typename EnableIf = void>
|
||||||
pmin(const Packet& a,
|
struct ptrue_impl {
|
||||||
const Packet& b) { return numext::mini(a, b); }
|
static EIGEN_DEVICE_FUNC inline Packet run(const Packet& /*a*/){
|
||||||
|
Packet b;
|
||||||
|
memset(static_cast<void*>(&b), 0xff, sizeof(Packet));
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/** \internal \returns the max of \a a and \a b (coeff-wise) */
|
// For non-trivial scalars, set to Scalar(1) (i.e. a non-zero value).
|
||||||
|
// Although this is technically not a valid bitmask, the scalar path for pselect
|
||||||
|
// uses a comparison to zero, so this should still work in most cases. We don't
|
||||||
|
// have another option, since the scalar type requires initialization.
|
||||||
|
template<typename T>
|
||||||
|
struct ptrue_impl<T,
|
||||||
|
typename internal::enable_if<is_scalar<T>::value && NumTraits<T>::RequireInitialization>::type > {
|
||||||
|
static EIGEN_DEVICE_FUNC inline T run(const T& /*a*/){
|
||||||
|
return T(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** \internal \returns one bits. */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
pmax(const Packet& a,
|
ptrue(const Packet& a) {
|
||||||
const Packet& b) { return numext::maxi(a, b); }
|
return ptrue_impl<Packet>::run(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
// In the general case, memset to zero.
|
||||||
|
template<typename Packet, typename EnableIf = void>
|
||||||
|
struct pzero_impl {
|
||||||
|
static EIGEN_DEVICE_FUNC inline Packet run(const Packet& /*a*/) {
|
||||||
|
Packet b;
|
||||||
|
memset(static_cast<void*>(&b), 0x00, sizeof(Packet));
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// For scalars, explicitly set to Scalar(0), since the underlying representation
|
||||||
|
// for zero may not consist of all-zero bits.
|
||||||
|
template<typename T>
|
||||||
|
struct pzero_impl<T,
|
||||||
|
typename internal::enable_if<is_scalar<T>::value>::type> {
|
||||||
|
static EIGEN_DEVICE_FUNC inline T run(const T& /*a*/) {
|
||||||
|
return T(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** \internal \returns packet of zeros */
|
||||||
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
|
pzero(const Packet& a) {
|
||||||
|
return pzero_impl<Packet>::run(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \internal \returns a <= b as a bit mask */
|
||||||
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
|
pcmp_le(const Packet& a, const Packet& b) { return a<=b ? ptrue(a) : pzero(a); }
|
||||||
|
|
||||||
|
/** \internal \returns a < b as a bit mask */
|
||||||
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
|
pcmp_lt(const Packet& a, const Packet& b) { return a<b ? ptrue(a) : pzero(a); }
|
||||||
|
|
||||||
|
/** \internal \returns a == b as a bit mask */
|
||||||
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
|
pcmp_eq(const Packet& a, const Packet& b) { return a==b ? ptrue(a) : pzero(a); }
|
||||||
|
|
||||||
|
/** \internal \returns a < b or a==NaN or b==NaN as a bit mask */
|
||||||
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
|
pcmp_lt_or_nan(const Packet& a, const Packet& b) { return a>=b ? pzero(a) : ptrue(a); }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct bit_and {
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR EIGEN_ALWAYS_INLINE T operator()(const T& a, const T& b) const {
|
||||||
|
return a & b;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct bit_or {
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR EIGEN_ALWAYS_INLINE T operator()(const T& a, const T& b) const {
|
||||||
|
return a | b;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct bit_xor {
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR EIGEN_ALWAYS_INLINE T operator()(const T& a, const T& b) const {
|
||||||
|
return a ^ b;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct bit_not {
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR EIGEN_ALWAYS_INLINE T operator()(const T& a) const {
|
||||||
|
return ~a;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Use operators &, |, ^, ~.
|
||||||
|
template<typename T>
|
||||||
|
struct operator_bitwise_helper {
|
||||||
|
EIGEN_DEVICE_FUNC static inline T bitwise_and(const T& a, const T& b) { return bit_and<T>()(a, b); }
|
||||||
|
EIGEN_DEVICE_FUNC static inline T bitwise_or(const T& a, const T& b) { return bit_or<T>()(a, b); }
|
||||||
|
EIGEN_DEVICE_FUNC static inline T bitwise_xor(const T& a, const T& b) { return bit_xor<T>()(a, b); }
|
||||||
|
EIGEN_DEVICE_FUNC static inline T bitwise_not(const T& a) { return bit_not<T>()(a); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Apply binary operations byte-by-byte
|
||||||
|
template<typename T>
|
||||||
|
struct bytewise_bitwise_helper {
|
||||||
|
EIGEN_DEVICE_FUNC static inline T bitwise_and(const T& a, const T& b) {
|
||||||
|
return binary(a, b, bit_and<unsigned char>());
|
||||||
|
}
|
||||||
|
EIGEN_DEVICE_FUNC static inline T bitwise_or(const T& a, const T& b) {
|
||||||
|
return binary(a, b, bit_or<unsigned char>());
|
||||||
|
}
|
||||||
|
EIGEN_DEVICE_FUNC static inline T bitwise_xor(const T& a, const T& b) {
|
||||||
|
return binary(a, b, bit_xor<unsigned char>());
|
||||||
|
}
|
||||||
|
EIGEN_DEVICE_FUNC static inline T bitwise_not(const T& a) {
|
||||||
|
return unary(a,bit_not<unsigned char>());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename Op>
|
||||||
|
EIGEN_DEVICE_FUNC static inline T unary(const T& a, Op op) {
|
||||||
|
const unsigned char* a_ptr = reinterpret_cast<const unsigned char*>(&a);
|
||||||
|
T c;
|
||||||
|
unsigned char* c_ptr = reinterpret_cast<unsigned char*>(&c);
|
||||||
|
for (size_t i = 0; i < sizeof(T); ++i) {
|
||||||
|
*c_ptr++ = op(*a_ptr++);
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Op>
|
||||||
|
EIGEN_DEVICE_FUNC static inline T binary(const T& a, const T& b, Op op) {
|
||||||
|
const unsigned char* a_ptr = reinterpret_cast<const unsigned char*>(&a);
|
||||||
|
const unsigned char* b_ptr = reinterpret_cast<const unsigned char*>(&b);
|
||||||
|
T c;
|
||||||
|
unsigned char* c_ptr = reinterpret_cast<unsigned char*>(&c);
|
||||||
|
for (size_t i = 0; i < sizeof(T); ++i) {
|
||||||
|
*c_ptr++ = op(*a_ptr++, *b_ptr++);
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// In the general case, use byte-by-byte manipulation.
|
||||||
|
template<typename T, typename EnableIf = void>
|
||||||
|
struct bitwise_helper : public bytewise_bitwise_helper<T> {};
|
||||||
|
|
||||||
|
// For integers or non-trivial scalars, use binary operators.
|
||||||
|
template<typename T>
|
||||||
|
struct bitwise_helper<T,
|
||||||
|
typename internal::enable_if<
|
||||||
|
is_scalar<T>::value && (NumTraits<T>::IsInteger || NumTraits<T>::RequireInitialization)>::type
|
||||||
|
> : public operator_bitwise_helper<T> {};
|
||||||
|
|
||||||
|
/** \internal \returns the bitwise and of \a a and \a b */
|
||||||
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
|
pand(const Packet& a, const Packet& b) {
|
||||||
|
return bitwise_helper<Packet>::bitwise_and(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \internal \returns the bitwise or of \a a and \a b */
|
||||||
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
|
por(const Packet& a, const Packet& b) {
|
||||||
|
return bitwise_helper<Packet>::bitwise_or(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \internal \returns the bitwise xor of \a a and \a b */
|
||||||
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
|
pxor(const Packet& a, const Packet& b) {
|
||||||
|
return bitwise_helper<Packet>::bitwise_xor(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \internal \returns the bitwise not of \a a */
|
||||||
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
|
pnot(const Packet& a) {
|
||||||
|
return bitwise_helper<Packet>::bitwise_not(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \internal \returns the bitwise and of \a a and not \a b */
|
||||||
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
|
pandnot(const Packet& a, const Packet& b) { return pand(a, pnot(b)); }
|
||||||
|
|
||||||
|
// In the general case, use bitwise select.
|
||||||
|
template<typename Packet, typename EnableIf = void>
|
||||||
|
struct pselect_impl {
|
||||||
|
static EIGEN_DEVICE_FUNC inline Packet run(const Packet& mask, const Packet& a, const Packet& b) {
|
||||||
|
return por(pand(a,mask),pandnot(b,mask));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// For scalars, use ternary select.
|
||||||
|
template<typename Packet>
|
||||||
|
struct pselect_impl<Packet,
|
||||||
|
typename internal::enable_if<is_scalar<Packet>::value>::type > {
|
||||||
|
static EIGEN_DEVICE_FUNC inline Packet run(const Packet& mask, const Packet& a, const Packet& b) {
|
||||||
|
return numext::equal_strict(mask, Packet(0)) ? b : a;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** \internal \returns \a or \b for each field in packet according to \mask */
|
||||||
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
|
pselect(const Packet& mask, const Packet& a, const Packet& b) {
|
||||||
|
return pselect_impl<Packet>::run(mask, a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> EIGEN_DEVICE_FUNC inline bool pselect<bool>(
|
||||||
|
const bool& cond, const bool& a, const bool& b) {
|
||||||
|
return cond ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \internal \returns the min or of \a a and \a b (coeff-wise)
|
||||||
|
If either \a a or \a b are NaN, the result is implementation defined. */
|
||||||
|
template<int NaNPropagation>
|
||||||
|
struct pminmax_impl {
|
||||||
|
template <typename Packet, typename Op>
|
||||||
|
static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a, const Packet& b, Op op) {
|
||||||
|
return op(a,b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** \internal \returns the min or max of \a a and \a b (coeff-wise)
|
||||||
|
If either \a a or \a b are NaN, NaN is returned. */
|
||||||
|
template<>
|
||||||
|
struct pminmax_impl<PropagateNaN> {
|
||||||
|
template <typename Packet, typename Op>
|
||||||
|
static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a, const Packet& b, Op op) {
|
||||||
|
Packet not_nan_mask_a = pcmp_eq(a, a);
|
||||||
|
Packet not_nan_mask_b = pcmp_eq(b, b);
|
||||||
|
return pselect(not_nan_mask_a,
|
||||||
|
pselect(not_nan_mask_b, op(a, b), b),
|
||||||
|
a);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** \internal \returns the min or max of \a a and \a b (coeff-wise)
|
||||||
|
If both \a a and \a b are NaN, NaN is returned.
|
||||||
|
Equivalent to std::fmin(a, b). */
|
||||||
|
template<>
|
||||||
|
struct pminmax_impl<PropagateNumbers> {
|
||||||
|
template <typename Packet, typename Op>
|
||||||
|
static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a, const Packet& b, Op op) {
|
||||||
|
Packet not_nan_mask_a = pcmp_eq(a, a);
|
||||||
|
Packet not_nan_mask_b = pcmp_eq(b, b);
|
||||||
|
return pselect(not_nan_mask_a,
|
||||||
|
pselect(not_nan_mask_b, op(a, b), a),
|
||||||
|
b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SYCL_DEVICE_ONLY
|
||||||
|
#define EIGEN_BINARY_OP_NAN_PROPAGATION(Type, Func) Func
|
||||||
|
#else
|
||||||
|
#define EIGEN_BINARY_OP_NAN_PROPAGATION(Type, Func) \
|
||||||
|
[](const Type& a, const Type& b) { \
|
||||||
|
return Func(a, b);}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** \internal \returns the min of \a a and \a b (coeff-wise).
|
||||||
|
If \a a or \b b is NaN, the return value is implementation defined. */
|
||||||
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
|
pmin(const Packet& a, const Packet& b) { return numext::mini(a,b); }
|
||||||
|
|
||||||
|
/** \internal \returns the min of \a a and \a b (coeff-wise).
|
||||||
|
NaNPropagation determines the NaN propagation semantics. */
|
||||||
|
template <int NaNPropagation, typename Packet>
|
||||||
|
EIGEN_DEVICE_FUNC inline Packet pmin(const Packet& a, const Packet& b) {
|
||||||
|
return pminmax_impl<NaNPropagation>::run(a, b, EIGEN_BINARY_OP_NAN_PROPAGATION(Packet, (pmin<Packet>)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \internal \returns the max of \a a and \a b (coeff-wise)
|
||||||
|
If \a a or \b b is NaN, the return value is implementation defined. */
|
||||||
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
|
pmax(const Packet& a, const Packet& b) { return numext::maxi(a, b); }
|
||||||
|
|
||||||
|
/** \internal \returns the max of \a a and \a b (coeff-wise).
|
||||||
|
NaNPropagation determines the NaN propagation semantics. */
|
||||||
|
template <int NaNPropagation, typename Packet>
|
||||||
|
EIGEN_DEVICE_FUNC inline Packet pmax(const Packet& a, const Packet& b) {
|
||||||
|
return pminmax_impl<NaNPropagation>::run(a, b, EIGEN_BINARY_OP_NAN_PROPAGATION(Packet,(pmax<Packet>)));
|
||||||
|
}
|
||||||
|
|
||||||
/** \internal \returns the absolute value of \a a */
|
/** \internal \returns the absolute value of \a a */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
pabs(const Packet& a) { using std::abs; return abs(a); }
|
pabs(const Packet& a) { return numext::abs(a); }
|
||||||
|
template<> EIGEN_DEVICE_FUNC inline unsigned int
|
||||||
|
pabs(const unsigned int& a) { return a; }
|
||||||
|
template<> EIGEN_DEVICE_FUNC inline unsigned long
|
||||||
|
pabs(const unsigned long& a) { return a; }
|
||||||
|
template<> EIGEN_DEVICE_FUNC inline unsigned long long
|
||||||
|
pabs(const unsigned long long& a) { return a; }
|
||||||
|
|
||||||
|
/** \internal \returns the addsub value of \a a,b */
|
||||||
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
|
paddsub(const Packet& a, const Packet& b) {
|
||||||
|
return pselect(peven_mask(a), padd(a, b), psub(a, b));
|
||||||
|
}
|
||||||
|
|
||||||
/** \internal \returns the phase angle of \a a */
|
/** \internal \returns the phase angle of \a a */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
parg(const Packet& a) { using numext::arg; return arg(a); }
|
parg(const Packet& a) { using numext::arg; return arg(a); }
|
||||||
|
|
||||||
/** \internal \returns the bitwise and of \a a and \a b */
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
|
||||||
pand(const Packet& a, const Packet& b) { return a & b; }
|
|
||||||
|
|
||||||
/** \internal \returns the bitwise or of \a a and \a b */
|
/** \internal \returns \a a logically shifted by N bits to the right */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<int N> EIGEN_DEVICE_FUNC inline int
|
||||||
por(const Packet& a, const Packet& b) { return a | b; }
|
parithmetic_shift_right(const int& a) { return a >> N; }
|
||||||
|
template<int N> EIGEN_DEVICE_FUNC inline long int
|
||||||
|
parithmetic_shift_right(const long int& a) { return a >> N; }
|
||||||
|
|
||||||
/** \internal \returns the bitwise xor of \a a and \a b */
|
/** \internal \returns \a a arithmetically shifted by N bits to the right */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<int N> EIGEN_DEVICE_FUNC inline int
|
||||||
pxor(const Packet& a, const Packet& b) { return a ^ b; }
|
plogical_shift_right(const int& a) { return static_cast<int>(static_cast<unsigned int>(a) >> N); }
|
||||||
|
template<int N> EIGEN_DEVICE_FUNC inline long int
|
||||||
|
plogical_shift_right(const long int& a) { return static_cast<long>(static_cast<unsigned long>(a) >> N); }
|
||||||
|
|
||||||
/** \internal \returns the bitwise andnot of \a a and \a b */
|
/** \internal \returns \a a shifted by N bits to the left */
|
||||||
|
template<int N> EIGEN_DEVICE_FUNC inline int
|
||||||
|
plogical_shift_left(const int& a) { return a << N; }
|
||||||
|
template<int N> EIGEN_DEVICE_FUNC inline long int
|
||||||
|
plogical_shift_left(const long int& a) { return a << N; }
|
||||||
|
|
||||||
|
/** \internal \returns the significant and exponent of the underlying floating point numbers
|
||||||
|
* See https://en.cppreference.com/w/cpp/numeric/math/frexp
|
||||||
|
*/
|
||||||
|
template <typename Packet>
|
||||||
|
EIGEN_DEVICE_FUNC inline Packet pfrexp(const Packet& a, Packet& exponent) {
|
||||||
|
int exp;
|
||||||
|
EIGEN_USING_STD(frexp);
|
||||||
|
Packet result = static_cast<Packet>(frexp(a, &exp));
|
||||||
|
exponent = static_cast<Packet>(exp);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \internal \returns a * 2^((int)exponent)
|
||||||
|
* See https://en.cppreference.com/w/cpp/numeric/math/ldexp
|
||||||
|
*/
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
pandnot(const Packet& a, const Packet& b) { return a & (!b); }
|
pldexp(const Packet &a, const Packet &exponent) {
|
||||||
|
EIGEN_USING_STD(ldexp)
|
||||||
|
return static_cast<Packet>(ldexp(a, static_cast<int>(exponent)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \internal \returns the min of \a a and \a b (coeff-wise) */
|
||||||
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
|
pabsdiff(const Packet& a, const Packet& b) { return pselect(pcmp_lt(a, b), psub(b, a), psub(a, b)); }
|
||||||
|
|
||||||
/** \internal \returns a packet version of \a *from, from must be 16 bytes aligned */
|
/** \internal \returns a packet version of \a *from, from must be 16 bytes aligned */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
|
|
@ -217,10 +602,22 @@ pload(const typename unpacket_traits<Packet>::type* from) { return *from; }
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
ploadu(const typename unpacket_traits<Packet>::type* from) { return *from; }
|
ploadu(const typename unpacket_traits<Packet>::type* from) { return *from; }
|
||||||
|
|
||||||
|
/** \internal \returns a packet version of \a *from, (un-aligned masked load)
|
||||||
|
* There is no generic implementation. We only have implementations for specialized
|
||||||
|
* cases. Generic case should not be called.
|
||||||
|
*/
|
||||||
|
template<typename Packet> EIGEN_DEVICE_FUNC inline
|
||||||
|
typename enable_if<unpacket_traits<Packet>::masked_load_available, Packet>::type
|
||||||
|
ploadu(const typename unpacket_traits<Packet>::type* from, typename unpacket_traits<Packet>::mask_t umask);
|
||||||
|
|
||||||
/** \internal \returns a packet with constant coefficients \a a, e.g.: (a,a,a,a) */
|
/** \internal \returns a packet with constant coefficients \a a, e.g.: (a,a,a,a) */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
pset1(const typename unpacket_traits<Packet>::type& a) { return a; }
|
pset1(const typename unpacket_traits<Packet>::type& a) { return a; }
|
||||||
|
|
||||||
|
/** \internal \returns a packet with constant coefficients set from bits */
|
||||||
|
template<typename Packet,typename BitsType> EIGEN_DEVICE_FUNC inline Packet
|
||||||
|
pset1frombits(BitsType a);
|
||||||
|
|
||||||
/** \internal \returns a packet with constant coefficients \a a[0], e.g.: (a[0],a[0],a[0],a[0]) */
|
/** \internal \returns a packet with constant coefficients \a a[0], e.g.: (a[0],a[0],a[0],a[0]) */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
pload1(const typename unpacket_traits<Packet>::type *a) { return pset1<Packet>(*a); }
|
pload1(const typename unpacket_traits<Packet>::type *a) { return pset1<Packet>(*a); }
|
||||||
|
|
@ -281,6 +678,20 @@ inline void pbroadcast2(const typename unpacket_traits<Packet>::type *a,
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet
|
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet
|
||||||
plset(const typename unpacket_traits<Packet>::type& a) { return a; }
|
plset(const typename unpacket_traits<Packet>::type& a) { return a; }
|
||||||
|
|
||||||
|
/** \internal \returns a packet with constant coefficients \a a, e.g.: (x, 0, x, 0),
|
||||||
|
where x is the value of all 1-bits. */
|
||||||
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||||
|
peven_mask(const Packet& /*a*/) {
|
||||||
|
typedef typename unpacket_traits<Packet>::type Scalar;
|
||||||
|
const size_t n = unpacket_traits<Packet>::size;
|
||||||
|
EIGEN_ALIGN_TO_BOUNDARY(sizeof(Packet)) Scalar elements[n];
|
||||||
|
for(size_t i = 0; i < n; ++i) {
|
||||||
|
memset(elements+i, ((i & 1) == 0 ? 0xff : 0), sizeof(Scalar));
|
||||||
|
}
|
||||||
|
return ploadu<Packet>(elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** \internal copy the packet \a from to \a *to, \a to must be 16 bytes aligned */
|
/** \internal copy the packet \a from to \a *to, \a to must be 16 bytes aligned */
|
||||||
template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline void pstore(Scalar* to, const Packet& from)
|
template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline void pstore(Scalar* to, const Packet& from)
|
||||||
{ (*to) = from; }
|
{ (*to) = from; }
|
||||||
|
|
@ -289,6 +700,15 @@ template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline void pstore(
|
||||||
template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline void pstoreu(Scalar* to, const Packet& from)
|
template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline void pstoreu(Scalar* to, const Packet& from)
|
||||||
{ (*to) = from; }
|
{ (*to) = from; }
|
||||||
|
|
||||||
|
/** \internal copy the packet \a from to \a *to, (un-aligned store with a mask)
|
||||||
|
* There is no generic implementation. We only have implementations for specialized
|
||||||
|
* cases. Generic case should not be called.
|
||||||
|
*/
|
||||||
|
template<typename Scalar, typename Packet>
|
||||||
|
EIGEN_DEVICE_FUNC inline
|
||||||
|
typename enable_if<unpacket_traits<Packet>::masked_store_available, void>::type
|
||||||
|
pstoreu(Scalar* to, const Packet& from, typename unpacket_traits<Packet>::mask_t umask);
|
||||||
|
|
||||||
template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline Packet pgather(const Scalar* from, Index /*stride*/)
|
template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline Packet pgather(const Scalar* from, Index /*stride*/)
|
||||||
{ return ploadu<Packet>(from); }
|
{ return ploadu<Packet>(from); }
|
||||||
|
|
||||||
|
|
@ -298,8 +718,10 @@ template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline void pstoreu
|
||||||
/** \internal tries to do cache prefetching of \a addr */
|
/** \internal tries to do cache prefetching of \a addr */
|
||||||
template<typename Scalar> EIGEN_DEVICE_FUNC inline void prefetch(const Scalar* addr)
|
template<typename Scalar> EIGEN_DEVICE_FUNC inline void prefetch(const Scalar* addr)
|
||||||
{
|
{
|
||||||
#ifdef __CUDA_ARCH__
|
#if defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||||
#if defined(__LP64__)
|
// do nothing
|
||||||
|
#elif defined(EIGEN_CUDA_ARCH)
|
||||||
|
#if defined(__LP64__) || EIGEN_OS_WIN64
|
||||||
// 64-bit pointer operand constraint for inlined asm
|
// 64-bit pointer operand constraint for inlined asm
|
||||||
asm(" prefetch.L1 [ %1 ];" : "=l"(addr) : "l"(addr));
|
asm(" prefetch.L1 [ %1 ];" : "=l"(addr) : "l"(addr));
|
||||||
#else
|
#else
|
||||||
|
|
@ -311,39 +733,6 @@ template<typename Scalar> EIGEN_DEVICE_FUNC inline void prefetch(const Scalar* a
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \internal \returns the first element of a packet */
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type pfirst(const Packet& a)
|
|
||||||
{ return a; }
|
|
||||||
|
|
||||||
/** \internal \returns a packet where the element i contains the sum of the packet of \a vec[i] */
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
|
||||||
preduxp(const Packet* vecs) { return vecs[0]; }
|
|
||||||
|
|
||||||
/** \internal \returns the sum of the elements of \a a*/
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux(const Packet& a)
|
|
||||||
{ return a; }
|
|
||||||
|
|
||||||
/** \internal \returns the sum of the elements of \a a by block of 4 elements.
|
|
||||||
* For a packet {a0, a1, a2, a3, a4, a5, a6, a7}, it returns a half packet {a0+a4, a1+a5, a2+a6, a3+a7}
|
|
||||||
* For packet-size smaller or equal to 4, this boils down to a noop.
|
|
||||||
*/
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline
|
|
||||||
typename conditional<(unpacket_traits<Packet>::size%8)==0,typename unpacket_traits<Packet>::half,Packet>::type
|
|
||||||
predux_downto4(const Packet& a)
|
|
||||||
{ return a; }
|
|
||||||
|
|
||||||
/** \internal \returns the product of the elements of \a a*/
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_mul(const Packet& a)
|
|
||||||
{ return a; }
|
|
||||||
|
|
||||||
/** \internal \returns the min of the elements of \a a*/
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_min(const Packet& a)
|
|
||||||
{ return a; }
|
|
||||||
|
|
||||||
/** \internal \returns the max of the elements of \a a*/
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_max(const Packet& a)
|
|
||||||
{ return a; }
|
|
||||||
|
|
||||||
/** \internal \returns the reversed elements of \a a*/
|
/** \internal \returns the reversed elements of \a a*/
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet preverse(const Packet& a)
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet preverse(const Packet& a)
|
||||||
{ return a; }
|
{ return a; }
|
||||||
|
|
@ -351,10 +740,7 @@ template<typename Packet> EIGEN_DEVICE_FUNC inline Packet preverse(const Packet&
|
||||||
/** \internal \returns \a a with real and imaginary part flipped (for complex type only) */
|
/** \internal \returns \a a with real and imaginary part flipped (for complex type only) */
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet pcplxflip(const Packet& a)
|
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet pcplxflip(const Packet& a)
|
||||||
{
|
{
|
||||||
// FIXME: uncomment the following in case we drop the internal imag and real functions.
|
return Packet(numext::imag(a),numext::real(a));
|
||||||
// using std::imag;
|
|
||||||
// using std::real;
|
|
||||||
return Packet(imag(a),real(a));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************
|
/**************************
|
||||||
|
|
@ -363,47 +749,51 @@ template<typename Packet> EIGEN_DEVICE_FUNC inline Packet pcplxflip(const Packet
|
||||||
|
|
||||||
/** \internal \returns the sine of \a a (coeff-wise) */
|
/** \internal \returns the sine of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet psin(const Packet& a) { using std::sin; return sin(a); }
|
Packet psin(const Packet& a) { EIGEN_USING_STD(sin); return sin(a); }
|
||||||
|
|
||||||
/** \internal \returns the cosine of \a a (coeff-wise) */
|
/** \internal \returns the cosine of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet pcos(const Packet& a) { using std::cos; return cos(a); }
|
Packet pcos(const Packet& a) { EIGEN_USING_STD(cos); return cos(a); }
|
||||||
|
|
||||||
/** \internal \returns the tan of \a a (coeff-wise) */
|
/** \internal \returns the tan of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet ptan(const Packet& a) { using std::tan; return tan(a); }
|
Packet ptan(const Packet& a) { EIGEN_USING_STD(tan); return tan(a); }
|
||||||
|
|
||||||
/** \internal \returns the arc sine of \a a (coeff-wise) */
|
/** \internal \returns the arc sine of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet pasin(const Packet& a) { using std::asin; return asin(a); }
|
Packet pasin(const Packet& a) { EIGEN_USING_STD(asin); return asin(a); }
|
||||||
|
|
||||||
/** \internal \returns the arc cosine of \a a (coeff-wise) */
|
/** \internal \returns the arc cosine of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet pacos(const Packet& a) { using std::acos; return acos(a); }
|
Packet pacos(const Packet& a) { EIGEN_USING_STD(acos); return acos(a); }
|
||||||
|
|
||||||
/** \internal \returns the arc tangent of \a a (coeff-wise) */
|
/** \internal \returns the arc tangent of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet patan(const Packet& a) { using std::atan; return atan(a); }
|
Packet patan(const Packet& a) { EIGEN_USING_STD(atan); return atan(a); }
|
||||||
|
|
||||||
/** \internal \returns the hyperbolic sine of \a a (coeff-wise) */
|
/** \internal \returns the hyperbolic sine of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet psinh(const Packet& a) { using std::sinh; return sinh(a); }
|
Packet psinh(const Packet& a) { EIGEN_USING_STD(sinh); return sinh(a); }
|
||||||
|
|
||||||
/** \internal \returns the hyperbolic cosine of \a a (coeff-wise) */
|
/** \internal \returns the hyperbolic cosine of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet pcosh(const Packet& a) { using std::cosh; return cosh(a); }
|
Packet pcosh(const Packet& a) { EIGEN_USING_STD(cosh); return cosh(a); }
|
||||||
|
|
||||||
/** \internal \returns the hyperbolic tan of \a a (coeff-wise) */
|
/** \internal \returns the hyperbolic tan of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet ptanh(const Packet& a) { using std::tanh; return tanh(a); }
|
Packet ptanh(const Packet& a) { EIGEN_USING_STD(tanh); return tanh(a); }
|
||||||
|
|
||||||
/** \internal \returns the exp of \a a (coeff-wise) */
|
/** \internal \returns the exp of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet pexp(const Packet& a) { using std::exp; return exp(a); }
|
Packet pexp(const Packet& a) { EIGEN_USING_STD(exp); return exp(a); }
|
||||||
|
|
||||||
|
/** \internal \returns the expm1 of \a a (coeff-wise) */
|
||||||
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
|
Packet pexpm1(const Packet& a) { return numext::expm1(a); }
|
||||||
|
|
||||||
/** \internal \returns the log of \a a (coeff-wise) */
|
/** \internal \returns the log of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet plog(const Packet& a) { using std::log; return log(a); }
|
Packet plog(const Packet& a) { EIGEN_USING_STD(log); return log(a); }
|
||||||
|
|
||||||
/** \internal \returns the log1p of \a a (coeff-wise) */
|
/** \internal \returns the log1p of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
|
|
@ -411,16 +801,24 @@ Packet plog1p(const Packet& a) { return numext::log1p(a); }
|
||||||
|
|
||||||
/** \internal \returns the log10 of \a a (coeff-wise) */
|
/** \internal \returns the log10 of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet plog10(const Packet& a) { using std::log10; return log10(a); }
|
Packet plog10(const Packet& a) { EIGEN_USING_STD(log10); return log10(a); }
|
||||||
|
|
||||||
|
/** \internal \returns the log10 of \a a (coeff-wise) */
|
||||||
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
|
Packet plog2(const Packet& a) {
|
||||||
|
typedef typename internal::unpacket_traits<Packet>::type Scalar;
|
||||||
|
return pmul(pset1<Packet>(Scalar(EIGEN_LOG2E)), plog(a));
|
||||||
|
}
|
||||||
|
|
||||||
/** \internal \returns the square-root of \a a (coeff-wise) */
|
/** \internal \returns the square-root of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet psqrt(const Packet& a) { using std::sqrt; return sqrt(a); }
|
Packet psqrt(const Packet& a) { return numext::sqrt(a); }
|
||||||
|
|
||||||
/** \internal \returns the reciprocal square-root of \a a (coeff-wise) */
|
/** \internal \returns the reciprocal square-root of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet prsqrt(const Packet& a) {
|
Packet prsqrt(const Packet& a) {
|
||||||
return pdiv(pset1<Packet>(1), psqrt(a));
|
typedef typename internal::unpacket_traits<Packet>::type Scalar;
|
||||||
|
return pdiv(pset1<Packet>(Scalar(1)), psqrt(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \internal \returns the rounded value of \a a (coeff-wise) */
|
/** \internal \returns the rounded value of \a a (coeff-wise) */
|
||||||
|
|
@ -431,15 +829,121 @@ Packet pround(const Packet& a) { using numext::round; return round(a); }
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet pfloor(const Packet& a) { using numext::floor; return floor(a); }
|
Packet pfloor(const Packet& a) { using numext::floor; return floor(a); }
|
||||||
|
|
||||||
|
/** \internal \returns the rounded value of \a a (coeff-wise) with current
|
||||||
|
* rounding mode */
|
||||||
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
|
Packet print(const Packet& a) { using numext::rint; return rint(a); }
|
||||||
|
|
||||||
/** \internal \returns the ceil of \a a (coeff-wise) */
|
/** \internal \returns the ceil of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet pceil(const Packet& a) { using numext::ceil; return ceil(a); }
|
Packet pceil(const Packet& a) { using numext::ceil; return ceil(a); }
|
||||||
|
|
||||||
|
/** \internal \returns the first element of a packet */
|
||||||
|
template<typename Packet>
|
||||||
|
EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type
|
||||||
|
pfirst(const Packet& a)
|
||||||
|
{ return a; }
|
||||||
|
|
||||||
|
/** \internal \returns the sum of the elements of upper and lower half of \a a if \a a is larger than 4.
|
||||||
|
* For a packet {a0, a1, a2, a3, a4, a5, a6, a7}, it returns a half packet {a0+a4, a1+a5, a2+a6, a3+a7}
|
||||||
|
* For packet-size smaller or equal to 4, this boils down to a noop.
|
||||||
|
*/
|
||||||
|
template<typename Packet>
|
||||||
|
EIGEN_DEVICE_FUNC inline typename conditional<(unpacket_traits<Packet>::size%8)==0,typename unpacket_traits<Packet>::half,Packet>::type
|
||||||
|
predux_half_dowto4(const Packet& a)
|
||||||
|
{ return a; }
|
||||||
|
|
||||||
|
// Slow generic implementation of Packet reduction.
|
||||||
|
template <typename Packet, typename Op>
|
||||||
|
EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type
|
||||||
|
predux_helper(const Packet& a, Op op) {
|
||||||
|
typedef typename unpacket_traits<Packet>::type Scalar;
|
||||||
|
const size_t n = unpacket_traits<Packet>::size;
|
||||||
|
EIGEN_ALIGN_TO_BOUNDARY(sizeof(Packet)) Scalar elements[n];
|
||||||
|
pstoreu<Scalar>(elements, a);
|
||||||
|
for(size_t k = n / 2; k > 0; k /= 2) {
|
||||||
|
for(size_t i = 0; i < k; ++i) {
|
||||||
|
elements[i] = op(elements[i], elements[i + k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return elements[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \internal \returns the sum of the elements of \a a*/
|
||||||
|
template<typename Packet>
|
||||||
|
EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type
|
||||||
|
predux(const Packet& a)
|
||||||
|
{
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \internal \returns the product of the elements of \a a */
|
||||||
|
template <typename Packet>
|
||||||
|
EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_mul(
|
||||||
|
const Packet& a) {
|
||||||
|
typedef typename unpacket_traits<Packet>::type Scalar;
|
||||||
|
return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmul<Scalar>)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \internal \returns the min of the elements of \a a */
|
||||||
|
template <typename Packet>
|
||||||
|
EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_min(
|
||||||
|
const Packet &a) {
|
||||||
|
typedef typename unpacket_traits<Packet>::type Scalar;
|
||||||
|
return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmin<PropagateFast, Scalar>)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <int NaNPropagation, typename Packet>
|
||||||
|
EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_min(
|
||||||
|
const Packet& a) {
|
||||||
|
typedef typename unpacket_traits<Packet>::type Scalar;
|
||||||
|
return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmin<NaNPropagation, Scalar>)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \internal \returns the min of the elements of \a a */
|
||||||
|
template <typename Packet>
|
||||||
|
EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_max(
|
||||||
|
const Packet &a) {
|
||||||
|
typedef typename unpacket_traits<Packet>::type Scalar;
|
||||||
|
return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmax<PropagateFast, Scalar>)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <int NaNPropagation, typename Packet>
|
||||||
|
EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_max(
|
||||||
|
const Packet& a) {
|
||||||
|
typedef typename unpacket_traits<Packet>::type Scalar;
|
||||||
|
return predux_helper(a, EIGEN_BINARY_OP_NAN_PROPAGATION(Scalar, (pmax<NaNPropagation, Scalar>)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef EIGEN_BINARY_OP_NAN_PROPAGATION
|
||||||
|
|
||||||
|
/** \internal \returns true if all coeffs of \a a means "true"
|
||||||
|
* It is supposed to be called on values returned by pcmp_*.
|
||||||
|
*/
|
||||||
|
// not needed yet
|
||||||
|
// template<typename Packet> EIGEN_DEVICE_FUNC inline bool predux_all(const Packet& a)
|
||||||
|
// { return bool(a); }
|
||||||
|
|
||||||
|
/** \internal \returns true if any coeffs of \a a means "true"
|
||||||
|
* It is supposed to be called on values returned by pcmp_*.
|
||||||
|
*/
|
||||||
|
template<typename Packet> EIGEN_DEVICE_FUNC inline bool predux_any(const Packet& a)
|
||||||
|
{
|
||||||
|
// Dirty but generic implementation where "true" is assumed to be non 0 and all the sames.
|
||||||
|
// It is expected that "true" is either:
|
||||||
|
// - Scalar(1)
|
||||||
|
// - bits full of ones (NaN for floats),
|
||||||
|
// - or first bit equals to 1 (1 for ints, smallest denormal for floats).
|
||||||
|
// For all these cases, taking the sum is just fine, and this boils down to a no-op for scalars.
|
||||||
|
typedef typename unpacket_traits<Packet>::type Scalar;
|
||||||
|
return numext::not_equal_strict(predux(a), Scalar(0));
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* The following functions might not have to be overwritten for vectorized types
|
* The following functions might not have to be overwritten for vectorized types
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
/** \internal copy a packet with constant coeficient \a a (e.g., [a,a,a,a]) to \a *to. \a to must be 16 bytes aligned */
|
/** \internal copy a packet with constant coefficient \a a (e.g., [a,a,a,a]) to \a *to. \a to must be 16 bytes aligned */
|
||||||
// NOTE: this function must really be templated on the packet type (think about different packet types for the same scalar type)
|
// NOTE: this function must really be templated on the packet type (think about different packet types for the same scalar type)
|
||||||
template<typename Packet>
|
template<typename Packet>
|
||||||
inline void pstore1(typename unpacket_traits<Packet>::type* to, const typename unpacket_traits<Packet>::type& a)
|
inline void pstore1(typename unpacket_traits<Packet>::type* to, const typename unpacket_traits<Packet>::type& a)
|
||||||
|
|
@ -487,47 +991,18 @@ EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet ploadt_ro(const typename unpacket_t
|
||||||
return ploadt<Packet, LoadMode>(from);
|
return ploadt<Packet, LoadMode>(from);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \internal default implementation of palign() allowing partial specialization */
|
|
||||||
template<int Offset,typename PacketType>
|
|
||||||
struct palign_impl
|
|
||||||
{
|
|
||||||
// by default data are aligned, so there is nothing to be done :)
|
|
||||||
static inline void run(PacketType&, const PacketType&) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \internal update \a first using the concatenation of the packet_size minus \a Offset last elements
|
|
||||||
* of \a first and \a Offset first elements of \a second.
|
|
||||||
*
|
|
||||||
* This function is currently only used to optimize matrix-vector products on unligned matrices.
|
|
||||||
* It takes 2 packets that represent a contiguous memory array, and returns a packet starting
|
|
||||||
* at the position \a Offset. For instance, for packets of 4 elements, we have:
|
|
||||||
* Input:
|
|
||||||
* - first = {f0,f1,f2,f3}
|
|
||||||
* - second = {s0,s1,s2,s3}
|
|
||||||
* Output:
|
|
||||||
* - if Offset==0 then {f0,f1,f2,f3}
|
|
||||||
* - if Offset==1 then {f1,f2,f3,s0}
|
|
||||||
* - if Offset==2 then {f2,f3,s0,s1}
|
|
||||||
* - if Offset==3 then {f3,s0,s1,s3}
|
|
||||||
*/
|
|
||||||
template<int Offset,typename PacketType>
|
|
||||||
inline void palign(PacketType& first, const PacketType& second)
|
|
||||||
{
|
|
||||||
palign_impl<Offset,PacketType>::run(first,second);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Fast complex products (GCC generates a function call which is very slow)
|
* Fast complex products (GCC generates a function call which is very slow)
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
// Eigen+CUDA does not support complexes.
|
// Eigen+CUDA does not support complexes.
|
||||||
#ifndef __CUDACC__
|
#if !defined(EIGEN_GPUCC)
|
||||||
|
|
||||||
template<> inline std::complex<float> pmul(const std::complex<float>& a, const std::complex<float>& b)
|
template<> inline std::complex<float> pmul(const std::complex<float>& a, const std::complex<float>& b)
|
||||||
{ return std::complex<float>(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); }
|
{ return std::complex<float>(a.real()*b.real() - a.imag()*b.imag(), a.imag()*b.real() + a.real()*b.imag()); }
|
||||||
|
|
||||||
template<> inline std::complex<double> pmul(const std::complex<double>& a, const std::complex<double>& b)
|
template<> inline std::complex<double> pmul(const std::complex<double>& a, const std::complex<double>& b)
|
||||||
{ return std::complex<double>(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); }
|
{ return std::complex<double>(a.real()*b.real() - a.imag()*b.imag(), a.imag()*b.real() + a.real()*b.imag()); }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -558,34 +1033,6 @@ pblend(const Selector<unpacket_traits<Packet>::size>& ifPacket, const Packet& th
|
||||||
return ifPacket.select[0] ? thenPacket : elsePacket;
|
return ifPacket.select[0] ? thenPacket : elsePacket;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \internal \returns \a a with the first coefficient replaced by the scalar b */
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
|
||||||
pinsertfirst(const Packet& a, typename unpacket_traits<Packet>::type b)
|
|
||||||
{
|
|
||||||
// Default implementation based on pblend.
|
|
||||||
// It must be specialized for higher performance.
|
|
||||||
Selector<unpacket_traits<Packet>::size> mask;
|
|
||||||
mask.select[0] = true;
|
|
||||||
// This for loop should be optimized away by the compiler.
|
|
||||||
for(Index i=1; i<unpacket_traits<Packet>::size; ++i)
|
|
||||||
mask.select[i] = false;
|
|
||||||
return pblend(mask, pset1<Packet>(b), a);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal \returns \a a with the last coefficient replaced by the scalar b */
|
|
||||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
|
||||||
pinsertlast(const Packet& a, typename unpacket_traits<Packet>::type b)
|
|
||||||
{
|
|
||||||
// Default implementation based on pblend.
|
|
||||||
// It must be specialized for higher performance.
|
|
||||||
Selector<unpacket_traits<Packet>::size> mask;
|
|
||||||
// This for loop should be optimized away by the compiler.
|
|
||||||
for(Index i=0; i<unpacket_traits<Packet>::size-1; ++i)
|
|
||||||
mask.select[i] = false;
|
|
||||||
mask.select[unpacket_traits<Packet>::size-1] = true;
|
|
||||||
return pblend(mask, pset1<Packet>(b), a);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
|
||||||
|
|
@ -66,21 +66,31 @@ namespace Eigen
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sinh,scalar_sinh_op,hyperbolic sine,\sa ArrayBase::sinh)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sinh,scalar_sinh_op,hyperbolic sine,\sa ArrayBase::sinh)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cosh,scalar_cosh_op,hyperbolic cosine,\sa ArrayBase::cosh)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cosh,scalar_cosh_op,hyperbolic cosine,\sa ArrayBase::cosh)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(tanh,scalar_tanh_op,hyperbolic tangent,\sa ArrayBase::tanh)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(tanh,scalar_tanh_op,hyperbolic tangent,\sa ArrayBase::tanh)
|
||||||
|
#if EIGEN_HAS_CXX11_MATH
|
||||||
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(asinh,scalar_asinh_op,inverse hyperbolic sine,\sa ArrayBase::asinh)
|
||||||
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(acosh,scalar_acosh_op,inverse hyperbolic cosine,\sa ArrayBase::acosh)
|
||||||
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(atanh,scalar_atanh_op,inverse hyperbolic tangent,\sa ArrayBase::atanh)
|
||||||
|
#endif
|
||||||
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(logistic,scalar_logistic_op,logistic function,\sa ArrayBase::logistic)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(lgamma,scalar_lgamma_op,natural logarithm of the gamma function,\sa ArrayBase::lgamma)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(lgamma,scalar_lgamma_op,natural logarithm of the gamma function,\sa ArrayBase::lgamma)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(digamma,scalar_digamma_op,derivative of lgamma,\sa ArrayBase::digamma)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(digamma,scalar_digamma_op,derivative of lgamma,\sa ArrayBase::digamma)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(erf,scalar_erf_op,error function,\sa ArrayBase::erf)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(erf,scalar_erf_op,error function,\sa ArrayBase::erf)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(erfc,scalar_erfc_op,complement error function,\sa ArrayBase::erfc)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(erfc,scalar_erfc_op,complement error function,\sa ArrayBase::erfc)
|
||||||
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(ndtri,scalar_ndtri_op,inverse normal distribution function,\sa ArrayBase::ndtri)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(exp,scalar_exp_op,exponential,\sa ArrayBase::exp)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(exp,scalar_exp_op,exponential,\sa ArrayBase::exp)
|
||||||
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(expm1,scalar_expm1_op,exponential of a value minus 1,\sa ArrayBase::expm1)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log,scalar_log_op,natural logarithm,\sa Eigen::log10 DOXCOMMA ArrayBase::log)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log,scalar_log_op,natural logarithm,\sa Eigen::log10 DOXCOMMA ArrayBase::log)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log1p,scalar_log1p_op,natural logarithm of 1 plus the value,\sa ArrayBase::log1p)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log1p,scalar_log1p_op,natural logarithm of 1 plus the value,\sa ArrayBase::log1p)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log10,scalar_log10_op,base 10 logarithm,\sa Eigen::log DOXCOMMA ArrayBase::log)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log10,scalar_log10_op,base 10 logarithm,\sa Eigen::log DOXCOMMA ArrayBase::log10)
|
||||||
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log2,scalar_log2_op,base 2 logarithm,\sa Eigen::log DOXCOMMA ArrayBase::log2)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(abs,scalar_abs_op,absolute value,\sa ArrayBase::abs DOXCOMMA MatrixBase::cwiseAbs)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(abs,scalar_abs_op,absolute value,\sa ArrayBase::abs DOXCOMMA MatrixBase::cwiseAbs)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(abs2,scalar_abs2_op,squared absolute value,\sa ArrayBase::abs2 DOXCOMMA MatrixBase::cwiseAbs2)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(abs2,scalar_abs2_op,squared absolute value,\sa ArrayBase::abs2 DOXCOMMA MatrixBase::cwiseAbs2)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(arg,scalar_arg_op,complex argument,\sa ArrayBase::arg)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(arg,scalar_arg_op,complex argument,\sa ArrayBase::arg DOXCOMMA MatrixBase::cwiseArg)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sqrt,scalar_sqrt_op,square root,\sa ArrayBase::sqrt DOXCOMMA MatrixBase::cwiseSqrt)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sqrt,scalar_sqrt_op,square root,\sa ArrayBase::sqrt DOXCOMMA MatrixBase::cwiseSqrt)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(rsqrt,scalar_rsqrt_op,reciprocal square root,\sa ArrayBase::rsqrt)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(rsqrt,scalar_rsqrt_op,reciprocal square root,\sa ArrayBase::rsqrt)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(square,scalar_square_op,square (power 2),\sa Eigen::abs2 DOXCOMMA Eigen::pow DOXCOMMA ArrayBase::square)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(square,scalar_square_op,square (power 2),\sa Eigen::abs2 DOXCOMMA Eigen::pow DOXCOMMA ArrayBase::square)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cube,scalar_cube_op,cube (power 3),\sa Eigen::pow DOXCOMMA ArrayBase::cube)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cube,scalar_cube_op,cube (power 3),\sa Eigen::pow DOXCOMMA ArrayBase::cube)
|
||||||
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(rint,scalar_rint_op,nearest integer,\sa Eigen::floor DOXCOMMA Eigen::ceil DOXCOMMA ArrayBase::round)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(round,scalar_round_op,nearest integer,\sa Eigen::floor DOXCOMMA Eigen::ceil DOXCOMMA ArrayBase::round)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(round,scalar_round_op,nearest integer,\sa Eigen::floor DOXCOMMA Eigen::ceil DOXCOMMA ArrayBase::round)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(floor,scalar_floor_op,nearest integer not greater than the giben value,\sa Eigen::ceil DOXCOMMA ArrayBase::floor)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(floor,scalar_floor_op,nearest integer not greater than the giben value,\sa Eigen::ceil DOXCOMMA ArrayBase::floor)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(ceil,scalar_ceil_op,nearest integer not less than the giben value,\sa Eigen::floor DOXCOMMA ArrayBase::ceil)
|
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(ceil,scalar_ceil_op,nearest integer not less than the giben value,\sa Eigen::floor DOXCOMMA ArrayBase::ceil)
|
||||||
|
|
@ -103,16 +113,17 @@ namespace Eigen
|
||||||
pow(const Eigen::ArrayBase<Derived>& x, const ScalarExponent& exponent);
|
pow(const Eigen::ArrayBase<Derived>& x, const ScalarExponent& exponent);
|
||||||
#else
|
#else
|
||||||
template <typename Derived,typename ScalarExponent>
|
template <typename Derived,typename ScalarExponent>
|
||||||
inline typename internal::enable_if< !(internal::is_same<typename Derived::Scalar,ScalarExponent>::value) && EIGEN_SCALAR_BINARY_SUPPORTED(pow,typename Derived::Scalar,ScalarExponent),
|
EIGEN_DEVICE_FUNC inline
|
||||||
const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(Derived,ScalarExponent,pow) >::type
|
EIGEN_MSVC10_WORKAROUND_BINARYOP_RETURN_TYPE(
|
||||||
pow(const Eigen::ArrayBase<Derived>& x, const ScalarExponent& exponent) {
|
const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(Derived,typename internal::promote_scalar_arg<typename Derived::Scalar
|
||||||
return x.derived().pow(exponent);
|
EIGEN_COMMA ScalarExponent EIGEN_COMMA
|
||||||
}
|
EIGEN_SCALAR_BINARY_SUPPORTED(pow,typename Derived::Scalar,ScalarExponent)>::type,pow))
|
||||||
|
pow(const Eigen::ArrayBase<Derived>& x, const ScalarExponent& exponent)
|
||||||
template<typename Derived>
|
{
|
||||||
inline const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(Derived,typename Derived::Scalar,pow)
|
typedef typename internal::promote_scalar_arg<typename Derived::Scalar,ScalarExponent,
|
||||||
pow(const Eigen::ArrayBase<Derived>& x, const typename Derived::Scalar& exponent) {
|
EIGEN_SCALAR_BINARY_SUPPORTED(pow,typename Derived::Scalar,ScalarExponent)>::type PromotedExponent;
|
||||||
return x.derived().pow(exponent);
|
return EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(Derived,PromotedExponent,pow)(x.derived(),
|
||||||
|
typename internal::plain_constant_type<Derived,PromotedExponent>::type(x.derived().rows(), x.derived().cols(), internal::scalar_constant_op<PromotedExponent>(exponent)));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -156,20 +167,16 @@ namespace Eigen
|
||||||
pow(const Scalar& x,const Eigen::ArrayBase<Derived>& x);
|
pow(const Scalar& x,const Eigen::ArrayBase<Derived>& x);
|
||||||
#else
|
#else
|
||||||
template <typename Scalar, typename Derived>
|
template <typename Scalar, typename Derived>
|
||||||
inline typename internal::enable_if< !(internal::is_same<typename Derived::Scalar,Scalar>::value) && EIGEN_SCALAR_BINARY_SUPPORTED(pow,Scalar,typename Derived::Scalar),
|
EIGEN_DEVICE_FUNC inline
|
||||||
const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar,Derived,pow) >::type
|
EIGEN_MSVC10_WORKAROUND_BINARYOP_RETURN_TYPE(
|
||||||
pow(const Scalar& x, const Eigen::ArrayBase<Derived>& exponents)
|
const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(typename internal::promote_scalar_arg<typename Derived::Scalar
|
||||||
{
|
EIGEN_COMMA Scalar EIGEN_COMMA
|
||||||
return EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar,Derived,pow)(
|
EIGEN_SCALAR_BINARY_SUPPORTED(pow,Scalar,typename Derived::Scalar)>::type,Derived,pow))
|
||||||
typename internal::plain_constant_type<Derived,Scalar>::type(exponents.rows(), exponents.cols(), x), exponents.derived() );
|
pow(const Scalar& x, const Eigen::ArrayBase<Derived>& exponents) {
|
||||||
}
|
typedef typename internal::promote_scalar_arg<typename Derived::Scalar,Scalar,
|
||||||
|
EIGEN_SCALAR_BINARY_SUPPORTED(pow,Scalar,typename Derived::Scalar)>::type PromotedScalar;
|
||||||
template<typename Derived>
|
return EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(PromotedScalar,Derived,pow)(
|
||||||
inline const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(typename Derived::Scalar,Derived,pow)
|
typename internal::plain_constant_type<Derived,PromotedScalar>::type(exponents.derived().rows(), exponents.derived().cols(), internal::scalar_constant_op<PromotedScalar>(x)), exponents.derived());
|
||||||
pow(const typename Derived::Scalar& x, const Eigen::ArrayBase<Derived>& exponents)
|
|
||||||
{
|
|
||||||
return EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(typename Derived::Scalar,Derived,pow)(
|
|
||||||
typename internal::plain_constant_type<Derived,typename Derived::Scalar>::type(exponents.rows(), exponents.cols(), x), exponents.derived() );
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat&
|
||||||
* - \b rowSuffix string printed at the end of each row
|
* - \b rowSuffix string printed at the end of each row
|
||||||
* - \b matPrefix string printed at the beginning of the matrix
|
* - \b matPrefix string printed at the beginning of the matrix
|
||||||
* - \b matSuffix string printed at the end of the matrix
|
* - \b matSuffix string printed at the end of the matrix
|
||||||
|
* - \b fill character printed to fill the empty space in aligned columns
|
||||||
*
|
*
|
||||||
* Example: \include IOFormat.cpp
|
* Example: \include IOFormat.cpp
|
||||||
* Output: \verbinclude IOFormat.out
|
* Output: \verbinclude IOFormat.out
|
||||||
|
|
@ -53,9 +54,9 @@ struct IOFormat
|
||||||
IOFormat(int _precision = StreamPrecision, int _flags = 0,
|
IOFormat(int _precision = StreamPrecision, int _flags = 0,
|
||||||
const std::string& _coeffSeparator = " ",
|
const std::string& _coeffSeparator = " ",
|
||||||
const std::string& _rowSeparator = "\n", const std::string& _rowPrefix="", const std::string& _rowSuffix="",
|
const std::string& _rowSeparator = "\n", const std::string& _rowPrefix="", const std::string& _rowSuffix="",
|
||||||
const std::string& _matPrefix="", const std::string& _matSuffix="")
|
const std::string& _matPrefix="", const std::string& _matSuffix="", const char _fill=' ')
|
||||||
: matPrefix(_matPrefix), matSuffix(_matSuffix), rowPrefix(_rowPrefix), rowSuffix(_rowSuffix), rowSeparator(_rowSeparator),
|
: matPrefix(_matPrefix), matSuffix(_matSuffix), rowPrefix(_rowPrefix), rowSuffix(_rowSuffix), rowSeparator(_rowSeparator),
|
||||||
rowSpacer(""), coeffSeparator(_coeffSeparator), precision(_precision), flags(_flags)
|
rowSpacer(""), coeffSeparator(_coeffSeparator), fill(_fill), precision(_precision), flags(_flags)
|
||||||
{
|
{
|
||||||
// TODO check if rowPrefix, rowSuffix or rowSeparator contains a newline
|
// TODO check if rowPrefix, rowSuffix or rowSeparator contains a newline
|
||||||
// don't add rowSpacer if columns are not to be aligned
|
// don't add rowSpacer if columns are not to be aligned
|
||||||
|
|
@ -71,6 +72,7 @@ struct IOFormat
|
||||||
std::string matPrefix, matSuffix;
|
std::string matPrefix, matSuffix;
|
||||||
std::string rowPrefix, rowSuffix, rowSeparator, rowSpacer;
|
std::string rowPrefix, rowSuffix, rowSeparator, rowSpacer;
|
||||||
std::string coeffSeparator;
|
std::string coeffSeparator;
|
||||||
|
char fill;
|
||||||
int precision;
|
int precision;
|
||||||
int flags;
|
int flags;
|
||||||
};
|
};
|
||||||
|
|
@ -128,6 +130,9 @@ struct significant_decimals_impl
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt)
|
std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt)
|
||||||
{
|
{
|
||||||
|
using internal::is_same;
|
||||||
|
using internal::conditional;
|
||||||
|
|
||||||
if(_m.size() == 0)
|
if(_m.size() == 0)
|
||||||
{
|
{
|
||||||
s << fmt.matPrefix << fmt.matSuffix;
|
s << fmt.matPrefix << fmt.matSuffix;
|
||||||
|
|
@ -136,6 +141,22 @@ std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat&
|
||||||
|
|
||||||
typename Derived::Nested m = _m;
|
typename Derived::Nested m = _m;
|
||||||
typedef typename Derived::Scalar Scalar;
|
typedef typename Derived::Scalar Scalar;
|
||||||
|
typedef typename
|
||||||
|
conditional<
|
||||||
|
is_same<Scalar, char>::value ||
|
||||||
|
is_same<Scalar, unsigned char>::value ||
|
||||||
|
is_same<Scalar, numext::int8_t>::value ||
|
||||||
|
is_same<Scalar, numext::uint8_t>::value,
|
||||||
|
int,
|
||||||
|
typename conditional<
|
||||||
|
is_same<Scalar, std::complex<char> >::value ||
|
||||||
|
is_same<Scalar, std::complex<unsigned char> >::value ||
|
||||||
|
is_same<Scalar, std::complex<numext::int8_t> >::value ||
|
||||||
|
is_same<Scalar, std::complex<numext::uint8_t> >::value,
|
||||||
|
std::complex<int>,
|
||||||
|
const Scalar&
|
||||||
|
>::type
|
||||||
|
>::type PrintType;
|
||||||
|
|
||||||
Index width = 0;
|
Index width = 0;
|
||||||
|
|
||||||
|
|
@ -172,23 +193,31 @@ std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat&
|
||||||
{
|
{
|
||||||
std::stringstream sstr;
|
std::stringstream sstr;
|
||||||
sstr.copyfmt(s);
|
sstr.copyfmt(s);
|
||||||
sstr << m.coeff(i,j);
|
sstr << static_cast<PrintType>(m.coeff(i,j));
|
||||||
width = std::max<Index>(width, Index(sstr.str().length()));
|
width = std::max<Index>(width, Index(sstr.str().length()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
std::streamsize old_width = s.width();
|
||||||
|
char old_fill_character = s.fill();
|
||||||
s << fmt.matPrefix;
|
s << fmt.matPrefix;
|
||||||
for(Index i = 0; i < m.rows(); ++i)
|
for(Index i = 0; i < m.rows(); ++i)
|
||||||
{
|
{
|
||||||
if (i)
|
if (i)
|
||||||
s << fmt.rowSpacer;
|
s << fmt.rowSpacer;
|
||||||
s << fmt.rowPrefix;
|
s << fmt.rowPrefix;
|
||||||
if(width) s.width(width);
|
if(width) {
|
||||||
s << m.coeff(i, 0);
|
s.fill(fmt.fill);
|
||||||
|
s.width(width);
|
||||||
|
}
|
||||||
|
s << static_cast<PrintType>(m.coeff(i, 0));
|
||||||
for(Index j = 1; j < m.cols(); ++j)
|
for(Index j = 1; j < m.cols(); ++j)
|
||||||
{
|
{
|
||||||
s << fmt.coeffSeparator;
|
s << fmt.coeffSeparator;
|
||||||
if (width) s.width(width);
|
if(width) {
|
||||||
s << m.coeff(i, j);
|
s.fill(fmt.fill);
|
||||||
|
s.width(width);
|
||||||
|
}
|
||||||
|
s << static_cast<PrintType>(m.coeff(i, j));
|
||||||
}
|
}
|
||||||
s << fmt.rowSuffix;
|
s << fmt.rowSuffix;
|
||||||
if( i < m.rows() - 1)
|
if( i < m.rows() - 1)
|
||||||
|
|
@ -196,6 +225,10 @@ std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat&
|
||||||
}
|
}
|
||||||
s << fmt.matSuffix;
|
s << fmt.matSuffix;
|
||||||
if(explicit_precision) s.precision(old_precision);
|
if(explicit_precision) s.precision(old_precision);
|
||||||
|
if(width) {
|
||||||
|
s.fill(old_fill_character);
|
||||||
|
s.width(old_width);
|
||||||
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,237 @@
|
||||||
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
|
// for linear algebra.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2017 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the Mozilla
|
||||||
|
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||||
|
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
#ifndef EIGEN_INDEXED_VIEW_H
|
||||||
|
#define EIGEN_INDEXED_VIEW_H
|
||||||
|
|
||||||
|
namespace Eigen {
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template<typename XprType, typename RowIndices, typename ColIndices>
|
||||||
|
struct traits<IndexedView<XprType, RowIndices, ColIndices> >
|
||||||
|
: traits<XprType>
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
RowsAtCompileTime = int(array_size<RowIndices>::value),
|
||||||
|
ColsAtCompileTime = int(array_size<ColIndices>::value),
|
||||||
|
MaxRowsAtCompileTime = RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime) : Dynamic,
|
||||||
|
MaxColsAtCompileTime = ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime) : Dynamic,
|
||||||
|
|
||||||
|
XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0,
|
||||||
|
IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1
|
||||||
|
: (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
|
||||||
|
: XprTypeIsRowMajor,
|
||||||
|
|
||||||
|
RowIncr = int(get_compile_time_incr<RowIndices>::value),
|
||||||
|
ColIncr = int(get_compile_time_incr<ColIndices>::value),
|
||||||
|
InnerIncr = IsRowMajor ? ColIncr : RowIncr,
|
||||||
|
OuterIncr = IsRowMajor ? RowIncr : ColIncr,
|
||||||
|
|
||||||
|
HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor),
|
||||||
|
XprInnerStride = HasSameStorageOrderAsXprType ? int(inner_stride_at_compile_time<XprType>::ret) : int(outer_stride_at_compile_time<XprType>::ret),
|
||||||
|
XprOuterstride = HasSameStorageOrderAsXprType ? int(outer_stride_at_compile_time<XprType>::ret) : int(inner_stride_at_compile_time<XprType>::ret),
|
||||||
|
|
||||||
|
InnerSize = XprTypeIsRowMajor ? ColsAtCompileTime : RowsAtCompileTime,
|
||||||
|
IsBlockAlike = InnerIncr==1 && OuterIncr==1,
|
||||||
|
IsInnerPannel = HasSameStorageOrderAsXprType && is_same<AllRange<InnerSize>,typename conditional<XprTypeIsRowMajor,ColIndices,RowIndices>::type>::value,
|
||||||
|
|
||||||
|
InnerStrideAtCompileTime = InnerIncr<0 || InnerIncr==DynamicIndex || XprInnerStride==Dynamic ? Dynamic : XprInnerStride * InnerIncr,
|
||||||
|
OuterStrideAtCompileTime = OuterIncr<0 || OuterIncr==DynamicIndex || XprOuterstride==Dynamic ? Dynamic : XprOuterstride * OuterIncr,
|
||||||
|
|
||||||
|
ReturnAsScalar = is_same<RowIndices,SingleRange>::value && is_same<ColIndices,SingleRange>::value,
|
||||||
|
ReturnAsBlock = (!ReturnAsScalar) && IsBlockAlike,
|
||||||
|
ReturnAsIndexedView = (!ReturnAsScalar) && (!ReturnAsBlock),
|
||||||
|
|
||||||
|
// FIXME we deal with compile-time strides if and only if we have DirectAccessBit flag,
|
||||||
|
// but this is too strict regarding negative strides...
|
||||||
|
DirectAccessMask = (int(InnerIncr)!=UndefinedIncr && int(OuterIncr)!=UndefinedIncr && InnerIncr>=0 && OuterIncr>=0) ? DirectAccessBit : 0,
|
||||||
|
FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
|
||||||
|
FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
|
||||||
|
FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0,
|
||||||
|
Flags = (traits<XprType>::Flags & (HereditaryBits | DirectAccessMask )) | FlagsLvalueBit | FlagsRowMajorBit | FlagsLinearAccessBit
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Block<XprType,RowsAtCompileTime,ColsAtCompileTime,IsInnerPannel> BlockType;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename XprType, typename RowIndices, typename ColIndices, typename StorageKind>
|
||||||
|
class IndexedViewImpl;
|
||||||
|
|
||||||
|
|
||||||
|
/** \class IndexedView
|
||||||
|
* \ingroup Core_Module
|
||||||
|
*
|
||||||
|
* \brief Expression of a non-sequential sub-matrix defined by arbitrary sequences of row and column indices
|
||||||
|
*
|
||||||
|
* \tparam XprType the type of the expression in which we are taking the intersections of sub-rows and sub-columns
|
||||||
|
* \tparam RowIndices the type of the object defining the sequence of row indices
|
||||||
|
* \tparam ColIndices the type of the object defining the sequence of column indices
|
||||||
|
*
|
||||||
|
* This class represents an expression of a sub-matrix (or sub-vector) defined as the intersection
|
||||||
|
* of sub-sets of rows and columns, that are themself defined by generic sequences of row indices \f$ \{r_0,r_1,..r_{m-1}\} \f$
|
||||||
|
* and column indices \f$ \{c_0,c_1,..c_{n-1} \}\f$. Let \f$ A \f$ be the nested matrix, then the resulting matrix \f$ B \f$ has \c m
|
||||||
|
* rows and \c n columns, and its entries are given by: \f$ B(i,j) = A(r_i,c_j) \f$.
|
||||||
|
*
|
||||||
|
* The \c RowIndices and \c ColIndices types must be compatible with the following API:
|
||||||
|
* \code
|
||||||
|
* <integral type> operator[](Index) const;
|
||||||
|
* Index size() const;
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* Typical supported types thus include:
|
||||||
|
* - std::vector<int>
|
||||||
|
* - std::valarray<int>
|
||||||
|
* - std::array<int>
|
||||||
|
* - Plain C arrays: int[N]
|
||||||
|
* - Eigen::ArrayXi
|
||||||
|
* - decltype(ArrayXi::LinSpaced(...))
|
||||||
|
* - Any view/expressions of the previous types
|
||||||
|
* - Eigen::ArithmeticSequence
|
||||||
|
* - Eigen::internal::AllRange (helper for Eigen::all)
|
||||||
|
* - Eigen::internal::SingleRange (helper for single index)
|
||||||
|
* - etc.
|
||||||
|
*
|
||||||
|
* In typical usages of %Eigen, this class should never be used directly. It is the return type of
|
||||||
|
* DenseBase::operator()(const RowIndices&, const ColIndices&).
|
||||||
|
*
|
||||||
|
* \sa class Block
|
||||||
|
*/
|
||||||
|
template<typename XprType, typename RowIndices, typename ColIndices>
|
||||||
|
class IndexedView : public IndexedViewImpl<XprType, RowIndices, ColIndices, typename internal::traits<XprType>::StorageKind>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename IndexedViewImpl<XprType, RowIndices, ColIndices, typename internal::traits<XprType>::StorageKind>::Base Base;
|
||||||
|
EIGEN_GENERIC_PUBLIC_INTERFACE(IndexedView)
|
||||||
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(IndexedView)
|
||||||
|
|
||||||
|
typedef typename internal::ref_selector<XprType>::non_const_type MatrixTypeNested;
|
||||||
|
typedef typename internal::remove_all<XprType>::type NestedExpression;
|
||||||
|
|
||||||
|
template<typename T0, typename T1>
|
||||||
|
IndexedView(XprType& xpr, const T0& rowIndices, const T1& colIndices)
|
||||||
|
: m_xpr(xpr), m_rowIndices(rowIndices), m_colIndices(colIndices)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/** \returns number of rows */
|
||||||
|
Index rows() const { return internal::size(m_rowIndices); }
|
||||||
|
|
||||||
|
/** \returns number of columns */
|
||||||
|
Index cols() const { return internal::size(m_colIndices); }
|
||||||
|
|
||||||
|
/** \returns the nested expression */
|
||||||
|
const typename internal::remove_all<XprType>::type&
|
||||||
|
nestedExpression() const { return m_xpr; }
|
||||||
|
|
||||||
|
/** \returns the nested expression */
|
||||||
|
typename internal::remove_reference<XprType>::type&
|
||||||
|
nestedExpression() { return m_xpr; }
|
||||||
|
|
||||||
|
/** \returns a const reference to the object storing/generating the row indices */
|
||||||
|
const RowIndices& rowIndices() const { return m_rowIndices; }
|
||||||
|
|
||||||
|
/** \returns a const reference to the object storing/generating the column indices */
|
||||||
|
const ColIndices& colIndices() const { return m_colIndices; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MatrixTypeNested m_xpr;
|
||||||
|
RowIndices m_rowIndices;
|
||||||
|
ColIndices m_colIndices;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Generic API dispatcher
|
||||||
|
template<typename XprType, typename RowIndices, typename ColIndices, typename StorageKind>
|
||||||
|
class IndexedViewImpl
|
||||||
|
: public internal::generic_xpr_base<IndexedView<XprType, RowIndices, ColIndices> >::type
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename internal::generic_xpr_base<IndexedView<XprType, RowIndices, ColIndices> >::type Base;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
|
||||||
|
template<typename ArgType, typename RowIndices, typename ColIndices>
|
||||||
|
struct unary_evaluator<IndexedView<ArgType, RowIndices, ColIndices>, IndexBased>
|
||||||
|
: evaluator_base<IndexedView<ArgType, RowIndices, ColIndices> >
|
||||||
|
{
|
||||||
|
typedef IndexedView<ArgType, RowIndices, ColIndices> XprType;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CoeffReadCost = evaluator<ArgType>::CoeffReadCost /* TODO + cost of row/col index */,
|
||||||
|
|
||||||
|
FlagsLinearAccessBit = (traits<XprType>::RowsAtCompileTime == 1 || traits<XprType>::ColsAtCompileTime == 1) ? LinearAccessBit : 0,
|
||||||
|
|
||||||
|
FlagsRowMajorBit = traits<XprType>::FlagsRowMajorBit,
|
||||||
|
|
||||||
|
Flags = (evaluator<ArgType>::Flags & (HereditaryBits & ~RowMajorBit /*| LinearAccessBit | DirectAccessBit*/)) | FlagsLinearAccessBit | FlagsRowMajorBit,
|
||||||
|
|
||||||
|
Alignment = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& xpr) : m_argImpl(xpr.nestedExpression()), m_xpr(xpr)
|
||||||
|
{
|
||||||
|
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef typename XprType::Scalar Scalar;
|
||||||
|
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
CoeffReturnType coeff(Index row, Index col) const
|
||||||
|
{
|
||||||
|
return m_argImpl.coeff(m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
Scalar& coeffRef(Index row, Index col)
|
||||||
|
{
|
||||||
|
return m_argImpl.coeffRef(m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
Scalar& coeffRef(Index index)
|
||||||
|
{
|
||||||
|
EIGEN_STATIC_ASSERT_LVALUE(XprType)
|
||||||
|
Index row = XprType::RowsAtCompileTime == 1 ? 0 : index;
|
||||||
|
Index col = XprType::RowsAtCompileTime == 1 ? index : 0;
|
||||||
|
return m_argImpl.coeffRef( m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
const Scalar& coeffRef(Index index) const
|
||||||
|
{
|
||||||
|
Index row = XprType::RowsAtCompileTime == 1 ? 0 : index;
|
||||||
|
Index col = XprType::RowsAtCompileTime == 1 ? index : 0;
|
||||||
|
return m_argImpl.coeffRef( m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
const CoeffReturnType coeff(Index index) const
|
||||||
|
{
|
||||||
|
Index row = XprType::RowsAtCompileTime == 1 ? 0 : index;
|
||||||
|
Index col = XprType::RowsAtCompileTime == 1 ? index : 0;
|
||||||
|
return m_argImpl.coeff( m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
evaluator<ArgType> m_argImpl;
|
||||||
|
const XprType& m_xpr;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace internal
|
||||||
|
|
||||||
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
#endif // EIGEN_INDEXED_VIEW_H
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// This file is part of Eigen, a lightweight C++ template library
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
// for linear algebra.
|
// for linear algebra.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2014 Gael Guennebaud <gael.guennebaud@inria.fr>
|
// Copyright (C) 2014-2019 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// This Source Code Form is subject to the terms of the Mozilla
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||||
|
|
@ -44,7 +44,6 @@ class Inverse : public InverseImpl<XprType,typename internal::traits<XprType>::S
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename XprType::StorageIndex StorageIndex;
|
typedef typename XprType::StorageIndex StorageIndex;
|
||||||
typedef typename XprType::PlainObject PlainObject;
|
|
||||||
typedef typename XprType::Scalar Scalar;
|
typedef typename XprType::Scalar Scalar;
|
||||||
typedef typename internal::ref_selector<XprType>::type XprTypeNested;
|
typedef typename internal::ref_selector<XprType>::type XprTypeNested;
|
||||||
typedef typename internal::remove_all<XprTypeNested>::type XprTypeNestedCleaned;
|
typedef typename internal::remove_all<XprTypeNested>::type XprTypeNestedCleaned;
|
||||||
|
|
@ -55,8 +54,8 @@ public:
|
||||||
: m_xpr(xpr)
|
: m_xpr(xpr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC Index rows() const { return m_xpr.rows(); }
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_xpr.cols(); }
|
||||||
EIGEN_DEVICE_FUNC Index cols() const { return m_xpr.cols(); }
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_xpr.rows(); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC const XprTypeNestedCleaned& nestedExpression() const { return m_xpr; }
|
EIGEN_DEVICE_FUNC const XprTypeNestedCleaned& nestedExpression() const { return m_xpr; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ private:
|
||||||
* \brief A matrix or vector expression mapping an existing array of data.
|
* \brief A matrix or vector expression mapping an existing array of data.
|
||||||
*
|
*
|
||||||
* \tparam PlainObjectType the equivalent matrix type of the mapped data
|
* \tparam PlainObjectType the equivalent matrix type of the mapped data
|
||||||
* \tparam MapOptions specifies the pointer alignment in bytes. It can be: \c #Aligned128, , \c #Aligned64, \c #Aligned32, \c #Aligned16, \c #Aligned8 or \c #Unaligned.
|
* \tparam MapOptions specifies the pointer alignment in bytes. It can be: \c #Aligned128, \c #Aligned64, \c #Aligned32, \c #Aligned16, \c #Aligned8 or \c #Unaligned.
|
||||||
* The default is \c #Unaligned.
|
* The default is \c #Unaligned.
|
||||||
* \tparam StrideType optionally specifies strides. By default, Map assumes the memory layout
|
* \tparam StrideType optionally specifies strides. By default, Map assumes the memory layout
|
||||||
* of an ordinary, contiguous array. This can be overridden by specifying strides.
|
* of an ordinary, contiguous array. This can be overridden by specifying strides.
|
||||||
|
|
@ -104,19 +104,19 @@ template<typename PlainObjectType, int MapOptions, typename StrideType> class Ma
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline PointerType cast_to_pointer_type(PointerArgType ptr) { return ptr; }
|
inline PointerType cast_to_pointer_type(PointerArgType ptr) { return ptr; }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index innerStride() const
|
inline Index innerStride() const
|
||||||
{
|
{
|
||||||
return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
|
return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index outerStride() const
|
inline Index outerStride() const
|
||||||
{
|
{
|
||||||
return int(StrideType::OuterStrideAtCompileTime) != 0 ? m_stride.outer()
|
return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
|
||||||
: int(internal::traits<Map>::OuterStrideAtCompileTime) != Dynamic ? Index(internal::traits<Map>::OuterStrideAtCompileTime)
|
: internal::traits<Map>::OuterStrideAtCompileTime != Dynamic ? Index(internal::traits<Map>::OuterStrideAtCompileTime)
|
||||||
: IsVectorAtCompileTime ? (this->size() * innerStride())
|
: IsVectorAtCompileTime ? (this->size() * innerStride())
|
||||||
: (int(Flags)&RowMajorBit) ? (this->cols() * innerStride())
|
: int(Flags)&RowMajorBit ? (this->cols() * innerStride())
|
||||||
: (this->rows() * innerStride());
|
: (this->rows() * innerStride());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,9 +87,11 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
|
||||||
typedef typename Base::CoeffReturnType CoeffReturnType;
|
typedef typename Base::CoeffReturnType CoeffReturnType;
|
||||||
|
|
||||||
/** \copydoc DenseBase::rows() */
|
/** \copydoc DenseBase::rows() */
|
||||||
EIGEN_DEVICE_FUNC inline Index rows() const { return m_rows.value(); }
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
|
inline Index rows() const EIGEN_NOEXCEPT { return m_rows.value(); }
|
||||||
/** \copydoc DenseBase::cols() */
|
/** \copydoc DenseBase::cols() */
|
||||||
EIGEN_DEVICE_FUNC inline Index cols() const { return m_cols.value(); }
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
|
inline Index cols() const EIGEN_NOEXCEPT { return m_cols.value(); }
|
||||||
|
|
||||||
/** Returns a pointer to the first coefficient of the matrix or vector.
|
/** Returns a pointer to the first coefficient of the matrix or vector.
|
||||||
*
|
*
|
||||||
|
|
@ -182,6 +184,8 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
EIGEN_DEFAULT_COPY_CONSTRUCTOR(MapBase)
|
||||||
|
EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(MapBase)
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
|
|
@ -294,6 +298,9 @@ template<typename Derived> class MapBase<Derived, WriteAccessors>
|
||||||
// In theory we could simply refer to Base:Base::operator=, but MSVC does not like Base::Base,
|
// In theory we could simply refer to Base:Base::operator=, but MSVC does not like Base::Base,
|
||||||
// see bugs 821 and 920.
|
// see bugs 821 and 920.
|
||||||
using ReadOnlyMapBase::Base::operator=;
|
using ReadOnlyMapBase::Base::operator=;
|
||||||
|
protected:
|
||||||
|
EIGEN_DEFAULT_COPY_CONSTRUCTOR(MapBase)
|
||||||
|
EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(MapBase)
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS
|
#undef EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -17,24 +17,28 @@ namespace internal {
|
||||||
|
|
||||||
/** \internal \returns the hyperbolic tan of \a a (coeff-wise)
|
/** \internal \returns the hyperbolic tan of \a a (coeff-wise)
|
||||||
Doesn't do anything fancy, just a 13/6-degree rational interpolant which
|
Doesn't do anything fancy, just a 13/6-degree rational interpolant which
|
||||||
is accurate up to a couple of ulp in the range [-9, 9], outside of which
|
is accurate up to a couple of ulps in the (approximate) range [-8, 8],
|
||||||
the tanh(x) = +/-1.
|
outside of which tanh(x) = +/-1 in single precision. The input is clamped
|
||||||
|
to the range [-c, c]. The value c is chosen as the smallest value where
|
||||||
|
the approximation evaluates to exactly 1. In the reange [-0.0004, 0.0004]
|
||||||
|
the approxmation tanh(x) ~= x is used for better accuracy as x tends to zero.
|
||||||
|
|
||||||
This implementation works on both scalars and packets.
|
This implementation works on both scalars and packets.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T generic_fast_tanh_float(const T& a_x)
|
T generic_fast_tanh_float(const T& a_x)
|
||||||
{
|
{
|
||||||
// Clamp the inputs to the range [-9, 9] since anything outside
|
// Clamp the inputs to the range [-c, c]
|
||||||
// this range is +/-1.0f in single-precision.
|
#ifdef EIGEN_VECTORIZE_FMA
|
||||||
const T plus_9 = pset1<T>(9.f);
|
const T plus_clamp = pset1<T>(7.99881172180175781f);
|
||||||
const T minus_9 = pset1<T>(-9.f);
|
const T minus_clamp = pset1<T>(-7.99881172180175781f);
|
||||||
// NOTE GCC prior to 6.3 might improperly optimize this max/min
|
#else
|
||||||
// step such that if a_x is nan, x will be either 9 or -9,
|
const T plus_clamp = pset1<T>(7.90531110763549805f);
|
||||||
// and tanh will return 1 or -1 instead of nan.
|
const T minus_clamp = pset1<T>(-7.90531110763549805f);
|
||||||
// This is supposed to be fixed in gcc6.3,
|
#endif
|
||||||
// see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72867
|
const T tiny = pset1<T>(0.0004f);
|
||||||
const T x = pmax(minus_9,pmin(plus_9,a_x));
|
const T x = pmax(pmin(a_x, plus_clamp), minus_clamp);
|
||||||
|
const T tiny_mask = pcmp_lt(pabs(a_x), tiny);
|
||||||
// The monomial coefficients of the numerator polynomial (odd).
|
// The monomial coefficients of the numerator polynomial (odd).
|
||||||
const T alpha_1 = pset1<T>(4.89352455891786e-03f);
|
const T alpha_1 = pset1<T>(4.89352455891786e-03f);
|
||||||
const T alpha_3 = pset1<T>(6.37261928875436e-04f);
|
const T alpha_3 = pset1<T>(6.37261928875436e-04f);
|
||||||
|
|
@ -62,20 +66,26 @@ T generic_fast_tanh_float(const T& a_x)
|
||||||
p = pmadd(x2, p, alpha_1);
|
p = pmadd(x2, p, alpha_1);
|
||||||
p = pmul(x, p);
|
p = pmul(x, p);
|
||||||
|
|
||||||
// Evaluate the denominator polynomial p.
|
// Evaluate the denominator polynomial q.
|
||||||
T q = pmadd(x2, beta_6, beta_4);
|
T q = pmadd(x2, beta_6, beta_4);
|
||||||
q = pmadd(x2, q, beta_2);
|
q = pmadd(x2, q, beta_2);
|
||||||
q = pmadd(x2, q, beta_0);
|
q = pmadd(x2, q, beta_0);
|
||||||
|
|
||||||
// Divide the numerator by the denominator.
|
// Divide the numerator by the denominator.
|
||||||
return pdiv(p, q);
|
return pselect(tiny_mask, x, pdiv(p, q));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RealScalar>
|
template<typename RealScalar>
|
||||||
EIGEN_STRONG_INLINE
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
RealScalar positive_real_hypot(const RealScalar& x, const RealScalar& y)
|
RealScalar positive_real_hypot(const RealScalar& x, const RealScalar& y)
|
||||||
{
|
{
|
||||||
EIGEN_USING_STD_MATH(sqrt);
|
// IEEE IEC 6059 special cases.
|
||||||
|
if ((numext::isinf)(x) || (numext::isinf)(y))
|
||||||
|
return NumTraits<RealScalar>::infinity();
|
||||||
|
if ((numext::isnan)(x) || (numext::isnan)(y))
|
||||||
|
return NumTraits<RealScalar>::quiet_NaN();
|
||||||
|
|
||||||
|
EIGEN_USING_STD(sqrt);
|
||||||
RealScalar p, qp;
|
RealScalar p, qp;
|
||||||
p = numext::maxi(x,y);
|
p = numext::maxi(x,y);
|
||||||
if(p==RealScalar(0)) return RealScalar(0);
|
if(p==RealScalar(0)) return RealScalar(0);
|
||||||
|
|
@ -87,13 +97,102 @@ template<typename Scalar>
|
||||||
struct hypot_impl
|
struct hypot_impl
|
||||||
{
|
{
|
||||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||||
static inline RealScalar run(const Scalar& x, const Scalar& y)
|
static EIGEN_DEVICE_FUNC
|
||||||
|
inline RealScalar run(const Scalar& x, const Scalar& y)
|
||||||
{
|
{
|
||||||
EIGEN_USING_STD_MATH(abs);
|
EIGEN_USING_STD(abs);
|
||||||
return positive_real_hypot<RealScalar>(abs(x), abs(y));
|
return positive_real_hypot<RealScalar>(abs(x), abs(y));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Generic complex sqrt implementation that correctly handles corner cases
|
||||||
|
// according to https://en.cppreference.com/w/cpp/numeric/complex/sqrt
|
||||||
|
template<typename T>
|
||||||
|
EIGEN_DEVICE_FUNC std::complex<T> complex_sqrt(const std::complex<T>& z) {
|
||||||
|
// Computes the principal sqrt of the input.
|
||||||
|
//
|
||||||
|
// For a complex square root of the number x + i*y. We want to find real
|
||||||
|
// numbers u and v such that
|
||||||
|
// (u + i*v)^2 = x + i*y <=>
|
||||||
|
// u^2 - v^2 + i*2*u*v = x + i*v.
|
||||||
|
// By equating the real and imaginary parts we get:
|
||||||
|
// u^2 - v^2 = x
|
||||||
|
// 2*u*v = y.
|
||||||
|
//
|
||||||
|
// For x >= 0, this has the numerically stable solution
|
||||||
|
// u = sqrt(0.5 * (x + sqrt(x^2 + y^2)))
|
||||||
|
// v = y / (2 * u)
|
||||||
|
// and for x < 0,
|
||||||
|
// v = sign(y) * sqrt(0.5 * (-x + sqrt(x^2 + y^2)))
|
||||||
|
// u = y / (2 * v)
|
||||||
|
//
|
||||||
|
// Letting w = sqrt(0.5 * (|x| + |z|)),
|
||||||
|
// if x == 0: u = w, v = sign(y) * w
|
||||||
|
// if x > 0: u = w, v = y / (2 * w)
|
||||||
|
// if x < 0: u = |y| / (2 * w), v = sign(y) * w
|
||||||
|
|
||||||
|
const T x = numext::real(z);
|
||||||
|
const T y = numext::imag(z);
|
||||||
|
const T zero = T(0);
|
||||||
|
const T w = numext::sqrt(T(0.5) * (numext::abs(x) + numext::hypot(x, y)));
|
||||||
|
|
||||||
|
return
|
||||||
|
(numext::isinf)(y) ? std::complex<T>(NumTraits<T>::infinity(), y)
|
||||||
|
: x == zero ? std::complex<T>(w, y < zero ? -w : w)
|
||||||
|
: x > zero ? std::complex<T>(w, y / (2 * w))
|
||||||
|
: std::complex<T>(numext::abs(y) / (2 * w), y < zero ? -w : w );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generic complex rsqrt implementation.
|
||||||
|
template<typename T>
|
||||||
|
EIGEN_DEVICE_FUNC std::complex<T> complex_rsqrt(const std::complex<T>& z) {
|
||||||
|
// Computes the principal reciprocal sqrt of the input.
|
||||||
|
//
|
||||||
|
// For a complex reciprocal square root of the number z = x + i*y. We want to
|
||||||
|
// find real numbers u and v such that
|
||||||
|
// (u + i*v)^2 = 1 / (x + i*y) <=>
|
||||||
|
// u^2 - v^2 + i*2*u*v = x/|z|^2 - i*v/|z|^2.
|
||||||
|
// By equating the real and imaginary parts we get:
|
||||||
|
// u^2 - v^2 = x/|z|^2
|
||||||
|
// 2*u*v = y/|z|^2.
|
||||||
|
//
|
||||||
|
// For x >= 0, this has the numerically stable solution
|
||||||
|
// u = sqrt(0.5 * (x + |z|)) / |z|
|
||||||
|
// v = -y / (2 * u * |z|)
|
||||||
|
// and for x < 0,
|
||||||
|
// v = -sign(y) * sqrt(0.5 * (-x + |z|)) / |z|
|
||||||
|
// u = -y / (2 * v * |z|)
|
||||||
|
//
|
||||||
|
// Letting w = sqrt(0.5 * (|x| + |z|)),
|
||||||
|
// if x == 0: u = w / |z|, v = -sign(y) * w / |z|
|
||||||
|
// if x > 0: u = w / |z|, v = -y / (2 * w * |z|)
|
||||||
|
// if x < 0: u = |y| / (2 * w * |z|), v = -sign(y) * w / |z|
|
||||||
|
|
||||||
|
const T x = numext::real(z);
|
||||||
|
const T y = numext::imag(z);
|
||||||
|
const T zero = T(0);
|
||||||
|
|
||||||
|
const T abs_z = numext::hypot(x, y);
|
||||||
|
const T w = numext::sqrt(T(0.5) * (numext::abs(x) + abs_z));
|
||||||
|
const T woz = w / abs_z;
|
||||||
|
// Corner cases consistent with 1/sqrt(z) on gcc/clang.
|
||||||
|
return
|
||||||
|
abs_z == zero ? std::complex<T>(NumTraits<T>::infinity(), NumTraits<T>::quiet_NaN())
|
||||||
|
: ((numext::isinf)(x) || (numext::isinf)(y)) ? std::complex<T>(zero, zero)
|
||||||
|
: x == zero ? std::complex<T>(woz, y < zero ? woz : -woz)
|
||||||
|
: x > zero ? std::complex<T>(woz, -y / (2 * w * abs_z))
|
||||||
|
: std::complex<T>(numext::abs(y) / (2 * w * abs_z), y < zero ? woz : -woz );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
EIGEN_DEVICE_FUNC std::complex<T> complex_log(const std::complex<T>& z) {
|
||||||
|
// Computes complex log.
|
||||||
|
T a = numext::abs(z);
|
||||||
|
EIGEN_USING_STD(atan2);
|
||||||
|
T b = atan2(z.imag(), z.real());
|
||||||
|
return std::complex<T>(numext::log(a), b);
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
|
||||||
|
|
@ -255,52 +255,92 @@ class Matrix
|
||||||
*
|
*
|
||||||
* \sa resize(Index,Index)
|
* \sa resize(Index,Index)
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
EIGEN_STRONG_INLINE Matrix() : Base()
|
Matrix() : Base()
|
||||||
{
|
{
|
||||||
Base::_check_template_params();
|
Base::_check_template_params();
|
||||||
EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
|
EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME is it still needed
|
// FIXME is it still needed
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
explicit Matrix(internal::constructor_without_unaligned_array_assert)
|
explicit Matrix(internal::constructor_without_unaligned_array_assert)
|
||||||
: Base(internal::constructor_without_unaligned_array_assert())
|
: Base(internal::constructor_without_unaligned_array_assert())
|
||||||
{ Base::_check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED }
|
{ Base::_check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED }
|
||||||
|
|
||||||
#if EIGEN_HAS_RVALUE_REFERENCES
|
#if EIGEN_HAS_RVALUE_REFERENCES
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
Matrix(Matrix&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_constructible<Scalar>::value)
|
Matrix(Matrix&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_constructible<Scalar>::value)
|
||||||
: Base(std::move(other))
|
: Base(std::move(other))
|
||||||
{
|
{
|
||||||
Base::_check_template_params();
|
Base::_check_template_params();
|
||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
Matrix& operator=(Matrix&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_assignable<Scalar>::value)
|
Matrix& operator=(Matrix&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_assignable<Scalar>::value)
|
||||||
{
|
{
|
||||||
other.swap(*this);
|
Base::operator=(std::move(other));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if EIGEN_HAS_CXX11
|
||||||
|
/** \copydoc PlainObjectBase(const Scalar&, const Scalar&, const Scalar&, const Scalar&, const ArgTypes&... args)
|
||||||
|
*
|
||||||
|
* Example: \include Matrix_variadic_ctor_cxx11.cpp
|
||||||
|
* Output: \verbinclude Matrix_variadic_ctor_cxx11.out
|
||||||
|
*
|
||||||
|
* \sa Matrix(const std::initializer_list<std::initializer_list<Scalar>>&)
|
||||||
|
*/
|
||||||
|
template <typename... ArgTypes>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
Matrix(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args)
|
||||||
|
: Base(a0, a1, a2, a3, args...) {}
|
||||||
|
|
||||||
|
/** \brief Constructs a Matrix and initializes it from the coefficients given as initializer-lists grouped by row. \cpp11
|
||||||
|
*
|
||||||
|
* In the general case, the constructor takes a list of rows, each row being represented as a list of coefficients:
|
||||||
|
*
|
||||||
|
* Example: \include Matrix_initializer_list_23_cxx11.cpp
|
||||||
|
* Output: \verbinclude Matrix_initializer_list_23_cxx11.out
|
||||||
|
*
|
||||||
|
* Each of the inner initializer lists must contain the exact same number of elements, otherwise an assertion is triggered.
|
||||||
|
*
|
||||||
|
* In the case of a compile-time column vector, implicit transposition from a single row is allowed.
|
||||||
|
* Therefore <code>VectorXd{{1,2,3,4,5}}</code> is legal and the more verbose syntax
|
||||||
|
* <code>RowVectorXd{{1},{2},{3},{4},{5}}</code> can be avoided:
|
||||||
|
*
|
||||||
|
* Example: \include Matrix_initializer_list_vector_cxx11.cpp
|
||||||
|
* Output: \verbinclude Matrix_initializer_list_vector_cxx11.out
|
||||||
|
*
|
||||||
|
* In the case of fixed-sized matrices, the initializer list sizes must exactly match the matrix sizes,
|
||||||
|
* and implicit transposition is allowed for compile-time vectors only.
|
||||||
|
*
|
||||||
|
* \sa Matrix(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args)
|
||||||
|
*/
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
explicit EIGEN_STRONG_INLINE Matrix(const std::initializer_list<std::initializer_list<Scalar>>& list) : Base(list) {}
|
||||||
|
#endif // end EIGEN_HAS_CXX11
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
|
||||||
// This constructor is for both 1x1 matrices and dynamic vectors
|
// This constructor is for both 1x1 matrices and dynamic vectors
|
||||||
template<typename T>
|
template<typename T>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
EIGEN_STRONG_INLINE explicit Matrix(const T& x)
|
explicit Matrix(const T& x)
|
||||||
{
|
{
|
||||||
Base::_check_template_params();
|
Base::_check_template_params();
|
||||||
Base::template _init1<T>(x);
|
Base::template _init1<T>(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T0, typename T1>
|
template<typename T0, typename T1>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
EIGEN_STRONG_INLINE Matrix(const T0& x, const T1& y)
|
Matrix(const T0& x, const T1& y)
|
||||||
{
|
{
|
||||||
Base::_check_template_params();
|
Base::_check_template_params();
|
||||||
Base::template _init2<T0,T1>(x, y);
|
Base::template _init2<T0,T1>(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/** \brief Constructs a fixed-sized matrix initialized with coefficients starting at \a data */
|
/** \brief Constructs a fixed-sized matrix initialized with coefficients starting at \a data */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
|
|
@ -319,7 +359,8 @@ class Matrix
|
||||||
* \c EIGEN_INITIALIZE_MATRICES_BY_{ZERO,\c NAN} macros (see \ref TopicPreprocessorDirectives).
|
* \c EIGEN_INITIALIZE_MATRICES_BY_{ZERO,\c NAN} macros (see \ref TopicPreprocessorDirectives).
|
||||||
*/
|
*/
|
||||||
EIGEN_STRONG_INLINE explicit Matrix(Index dim);
|
EIGEN_STRONG_INLINE explicit Matrix(Index dim);
|
||||||
/** \brief Constructs an initialized 1x1 matrix with the given coefficient */
|
/** \brief Constructs an initialized 1x1 matrix with the given coefficient
|
||||||
|
* \sa Matrix(const Scalar&, const Scalar&, const Scalar&, const Scalar&, const ArgTypes&...) */
|
||||||
Matrix(const Scalar& x);
|
Matrix(const Scalar& x);
|
||||||
/** \brief Constructs an uninitialized matrix with \a rows rows and \a cols columns.
|
/** \brief Constructs an uninitialized matrix with \a rows rows and \a cols columns.
|
||||||
*
|
*
|
||||||
|
|
@ -336,11 +377,14 @@ class Matrix
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
Matrix(Index rows, Index cols);
|
Matrix(Index rows, Index cols);
|
||||||
|
|
||||||
/** \brief Constructs an initialized 2D vector with given coefficients */
|
/** \brief Constructs an initialized 2D vector with given coefficients
|
||||||
|
* \sa Matrix(const Scalar&, const Scalar&, const Scalar&, const Scalar&, const ArgTypes&...) */
|
||||||
Matrix(const Scalar& x, const Scalar& y);
|
Matrix(const Scalar& x, const Scalar& y);
|
||||||
#endif
|
#endif // end EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
|
||||||
/** \brief Constructs an initialized 3D vector with given coefficients */
|
/** \brief Constructs an initialized 3D vector with given coefficients
|
||||||
|
* \sa Matrix(const Scalar&, const Scalar&, const Scalar&, const Scalar&, const ArgTypes&...)
|
||||||
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z)
|
EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z)
|
||||||
{
|
{
|
||||||
|
|
@ -350,7 +394,9 @@ class Matrix
|
||||||
m_storage.data()[1] = y;
|
m_storage.data()[1] = y;
|
||||||
m_storage.data()[2] = z;
|
m_storage.data()[2] = z;
|
||||||
}
|
}
|
||||||
/** \brief Constructs an initialized 4D vector with given coefficients */
|
/** \brief Constructs an initialized 4D vector with given coefficients
|
||||||
|
* \sa Matrix(const Scalar&, const Scalar&, const Scalar&, const Scalar&, const ArgTypes&...)
|
||||||
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w)
|
EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w)
|
||||||
{
|
{
|
||||||
|
|
@ -377,8 +423,10 @@ class Matrix
|
||||||
: Base(other.derived())
|
: Base(other.derived())
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline Index innerStride() const { return 1; }
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
EIGEN_DEVICE_FUNC inline Index outerStride() const { return this->innerSize(); }
|
inline Index innerStride() const EIGEN_NOEXCEPT { return 1; }
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
|
inline Index outerStride() const EIGEN_NOEXCEPT { return this->innerSize(); }
|
||||||
|
|
||||||
/////////// Geometry module ///////////
|
/////////// Geometry module ///////////
|
||||||
|
|
||||||
|
|
@ -405,7 +453,7 @@ class Matrix
|
||||||
*
|
*
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
*
|
*
|
||||||
* Eigen defines several typedef shortcuts for most common matrix and vector types.
|
* %Eigen defines several typedef shortcuts for most common matrix and vector types.
|
||||||
*
|
*
|
||||||
* The general patterns are the following:
|
* The general patterns are the following:
|
||||||
*
|
*
|
||||||
|
|
@ -418,6 +466,15 @@ class Matrix
|
||||||
* There are also \c VectorSizeType and \c RowVectorSizeType which are self-explanatory. For example, \c Vector4cf is
|
* There are also \c VectorSizeType and \c RowVectorSizeType which are self-explanatory. For example, \c Vector4cf is
|
||||||
* a fixed-size vector of 4 complex floats.
|
* a fixed-size vector of 4 complex floats.
|
||||||
*
|
*
|
||||||
|
* With \cpp11, template alias are also defined for common sizes.
|
||||||
|
* They follow the same pattern as above except that the scalar type suffix is replaced by a
|
||||||
|
* template parameter, i.e.:
|
||||||
|
* - `MatrixSize<Type>` where `Size` can be \c 2,\c 3,\c 4 for fixed size square matrices or \c X for dynamic size.
|
||||||
|
* - `MatrixXSize<Type>` and `MatrixSizeX<Type>` where `Size` can be \c 2,\c 3,\c 4 for hybrid dynamic/fixed matrices.
|
||||||
|
* - `VectorSize<Type>` and `RowVectorSize<Type>` for column and row vectors.
|
||||||
|
*
|
||||||
|
* With \cpp11, you can also use fully generic column and row vector types: `Vector<Type,Size>` and `RowVector<Type,Size>`.
|
||||||
|
*
|
||||||
* \sa class Matrix
|
* \sa class Matrix
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -454,6 +511,55 @@ EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex<double>, cd)
|
||||||
#undef EIGEN_MAKE_TYPEDEFS
|
#undef EIGEN_MAKE_TYPEDEFS
|
||||||
#undef EIGEN_MAKE_FIXED_TYPEDEFS
|
#undef EIGEN_MAKE_FIXED_TYPEDEFS
|
||||||
|
|
||||||
|
#if EIGEN_HAS_CXX11
|
||||||
|
|
||||||
|
#define EIGEN_MAKE_TYPEDEFS(Size, SizeSuffix) \
|
||||||
|
/** \ingroup matrixtypedefs */ \
|
||||||
|
/** \brief \cpp11 */ \
|
||||||
|
template <typename Type> \
|
||||||
|
using Matrix##SizeSuffix = Matrix<Type, Size, Size>; \
|
||||||
|
/** \ingroup matrixtypedefs */ \
|
||||||
|
/** \brief \cpp11 */ \
|
||||||
|
template <typename Type> \
|
||||||
|
using Vector##SizeSuffix = Matrix<Type, Size, 1>; \
|
||||||
|
/** \ingroup matrixtypedefs */ \
|
||||||
|
/** \brief \cpp11 */ \
|
||||||
|
template <typename Type> \
|
||||||
|
using RowVector##SizeSuffix = Matrix<Type, 1, Size>;
|
||||||
|
|
||||||
|
#define EIGEN_MAKE_FIXED_TYPEDEFS(Size) \
|
||||||
|
/** \ingroup matrixtypedefs */ \
|
||||||
|
/** \brief \cpp11 */ \
|
||||||
|
template <typename Type> \
|
||||||
|
using Matrix##Size##X = Matrix<Type, Size, Dynamic>; \
|
||||||
|
/** \ingroup matrixtypedefs */ \
|
||||||
|
/** \brief \cpp11 */ \
|
||||||
|
template <typename Type> \
|
||||||
|
using Matrix##X##Size = Matrix<Type, Dynamic, Size>;
|
||||||
|
|
||||||
|
EIGEN_MAKE_TYPEDEFS(2, 2)
|
||||||
|
EIGEN_MAKE_TYPEDEFS(3, 3)
|
||||||
|
EIGEN_MAKE_TYPEDEFS(4, 4)
|
||||||
|
EIGEN_MAKE_TYPEDEFS(Dynamic, X)
|
||||||
|
EIGEN_MAKE_FIXED_TYPEDEFS(2)
|
||||||
|
EIGEN_MAKE_FIXED_TYPEDEFS(3)
|
||||||
|
EIGEN_MAKE_FIXED_TYPEDEFS(4)
|
||||||
|
|
||||||
|
/** \ingroup matrixtypedefs
|
||||||
|
* \brief \cpp11 */
|
||||||
|
template <typename Type, int Size>
|
||||||
|
using Vector = Matrix<Type, Size, 1>;
|
||||||
|
|
||||||
|
/** \ingroup matrixtypedefs
|
||||||
|
* \brief \cpp11 */
|
||||||
|
template <typename Type, int Size>
|
||||||
|
using RowVector = Matrix<Type, 1, Size>;
|
||||||
|
|
||||||
|
#undef EIGEN_MAKE_TYPEDEFS
|
||||||
|
#undef EIGEN_MAKE_FIXED_TYPEDEFS
|
||||||
|
|
||||||
|
#endif // EIGEN_HAS_CXX11
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_MATRIX_H
|
#endif // EIGEN_MATRIX_H
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ template<typename Derived> class MatrixBase
|
||||||
using Base::coeffRef;
|
using Base::coeffRef;
|
||||||
using Base::lazyAssign;
|
using Base::lazyAssign;
|
||||||
using Base::eval;
|
using Base::eval;
|
||||||
|
using Base::operator-;
|
||||||
using Base::operator+=;
|
using Base::operator+=;
|
||||||
using Base::operator-=;
|
using Base::operator-=;
|
||||||
using Base::operator*=;
|
using Base::operator*=;
|
||||||
|
|
@ -122,7 +123,6 @@ template<typename Derived> class MatrixBase
|
||||||
|
|
||||||
#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::MatrixBase
|
#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::MatrixBase
|
||||||
#define EIGEN_DOC_UNARY_ADDONS(X,Y)
|
#define EIGEN_DOC_UNARY_ADDONS(X,Y)
|
||||||
# include "../plugins/CommonCwiseUnaryOps.h"
|
|
||||||
# include "../plugins/CommonCwiseBinaryOps.h"
|
# include "../plugins/CommonCwiseBinaryOps.h"
|
||||||
# include "../plugins/MatrixCwiseUnaryOps.h"
|
# include "../plugins/MatrixCwiseUnaryOps.h"
|
||||||
# include "../plugins/MatrixCwiseBinaryOps.h"
|
# include "../plugins/MatrixCwiseBinaryOps.h"
|
||||||
|
|
@ -268,6 +268,8 @@ template<typename Derived> class MatrixBase
|
||||||
Derived& setIdentity();
|
Derived& setIdentity();
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
Derived& setIdentity(Index rows, Index cols);
|
Derived& setIdentity(Index rows, Index cols);
|
||||||
|
EIGEN_DEVICE_FUNC Derived& setUnit(Index i);
|
||||||
|
EIGEN_DEVICE_FUNC Derived& setUnit(Index newSize, Index i);
|
||||||
|
|
||||||
bool isIdentity(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
bool isIdentity(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||||
bool isDiagonal(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
bool isDiagonal(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||||
|
|
@ -296,7 +298,7 @@ template<typename Derived> class MatrixBase
|
||||||
EIGEN_DEVICE_FUNC inline bool operator!=(const MatrixBase<OtherDerived>& other) const
|
EIGEN_DEVICE_FUNC inline bool operator!=(const MatrixBase<OtherDerived>& other) const
|
||||||
{ return cwiseNotEqual(other).any(); }
|
{ return cwiseNotEqual(other).any(); }
|
||||||
|
|
||||||
NoAlias<Derived,Eigen::MatrixBase > noalias();
|
NoAlias<Derived,Eigen::MatrixBase > EIGEN_DEVICE_FUNC noalias();
|
||||||
|
|
||||||
// TODO forceAlignedAccess is temporarily disabled
|
// TODO forceAlignedAccess is temporarily disabled
|
||||||
// Need to find a nicer workaround.
|
// Need to find a nicer workaround.
|
||||||
|
|
@ -326,6 +328,7 @@ template<typename Derived> class MatrixBase
|
||||||
|
|
||||||
inline const PartialPivLU<PlainObject> lu() const;
|
inline const PartialPivLU<PlainObject> lu() const;
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
inline const Inverse<Derived> inverse() const;
|
inline const Inverse<Derived> inverse() const;
|
||||||
|
|
||||||
template<typename ResultType>
|
template<typename ResultType>
|
||||||
|
|
@ -335,12 +338,15 @@ template<typename Derived> class MatrixBase
|
||||||
bool& invertible,
|
bool& invertible,
|
||||||
const RealScalar& absDeterminantThreshold = NumTraits<Scalar>::dummy_precision()
|
const RealScalar& absDeterminantThreshold = NumTraits<Scalar>::dummy_precision()
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
template<typename ResultType>
|
template<typename ResultType>
|
||||||
inline void computeInverseWithCheck(
|
inline void computeInverseWithCheck(
|
||||||
ResultType& inverse,
|
ResultType& inverse,
|
||||||
bool& invertible,
|
bool& invertible,
|
||||||
const RealScalar& absDeterminantThreshold = NumTraits<Scalar>::dummy_precision()
|
const RealScalar& absDeterminantThreshold = NumTraits<Scalar>::dummy_precision()
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
Scalar determinant() const;
|
Scalar determinant() const;
|
||||||
|
|
||||||
/////////// Cholesky module ///////////
|
/////////// Cholesky module ///////////
|
||||||
|
|
@ -412,15 +418,19 @@ template<typename Derived> class MatrixBase
|
||||||
|
|
||||||
////////// Householder module ///////////
|
////////// Householder module ///////////
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
void makeHouseholderInPlace(Scalar& tau, RealScalar& beta);
|
void makeHouseholderInPlace(Scalar& tau, RealScalar& beta);
|
||||||
template<typename EssentialPart>
|
template<typename EssentialPart>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
void makeHouseholder(EssentialPart& essential,
|
void makeHouseholder(EssentialPart& essential,
|
||||||
Scalar& tau, RealScalar& beta) const;
|
Scalar& tau, RealScalar& beta) const;
|
||||||
template<typename EssentialPart>
|
template<typename EssentialPart>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
void applyHouseholderOnTheLeft(const EssentialPart& essential,
|
void applyHouseholderOnTheLeft(const EssentialPart& essential,
|
||||||
const Scalar& tau,
|
const Scalar& tau,
|
||||||
Scalar* workspace);
|
Scalar* workspace);
|
||||||
template<typename EssentialPart>
|
template<typename EssentialPart>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
void applyHouseholderOnTheRight(const EssentialPart& essential,
|
void applyHouseholderOnTheRight(const EssentialPart& essential,
|
||||||
const Scalar& tau,
|
const Scalar& tau,
|
||||||
Scalar* workspace);
|
Scalar* workspace);
|
||||||
|
|
@ -428,8 +438,10 @@ template<typename Derived> class MatrixBase
|
||||||
///////// Jacobi module /////////
|
///////// Jacobi module /////////
|
||||||
|
|
||||||
template<typename OtherScalar>
|
template<typename OtherScalar>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
void applyOnTheLeft(Index p, Index q, const JacobiRotation<OtherScalar>& j);
|
void applyOnTheLeft(Index p, Index q, const JacobiRotation<OtherScalar>& j);
|
||||||
template<typename OtherScalar>
|
template<typename OtherScalar>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
void applyOnTheRight(Index p, Index q, const JacobiRotation<OtherScalar>& j);
|
void applyOnTheRight(Index p, Index q, const JacobiRotation<OtherScalar>& j);
|
||||||
|
|
||||||
///////// SparseCore module /////////
|
///////// SparseCore module /////////
|
||||||
|
|
@ -456,6 +468,11 @@ template<typename Derived> class MatrixBase
|
||||||
const MatrixFunctionReturnValue<Derived> matrixFunction(StemFunction f) const;
|
const MatrixFunctionReturnValue<Derived> matrixFunction(StemFunction f) const;
|
||||||
EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, cosh, hyperbolic cosine)
|
EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, cosh, hyperbolic cosine)
|
||||||
EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, sinh, hyperbolic sine)
|
EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, sinh, hyperbolic sine)
|
||||||
|
#if EIGEN_HAS_CXX11_MATH
|
||||||
|
EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, atanh, inverse hyperbolic cosine)
|
||||||
|
EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, acosh, inverse hyperbolic cosine)
|
||||||
|
EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, asinh, inverse hyperbolic sine)
|
||||||
|
#endif
|
||||||
EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, cos, cosine)
|
EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, cos, cosine)
|
||||||
EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, sin, sine)
|
EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, sin, sine)
|
||||||
EIGEN_MATRIX_FUNCTION(MatrixSquareRootReturnValue, sqrt, square root)
|
EIGEN_MATRIX_FUNCTION(MatrixSquareRootReturnValue, sqrt, square root)
|
||||||
|
|
@ -464,7 +481,8 @@ template<typename Derived> class MatrixBase
|
||||||
EIGEN_MATRIX_FUNCTION_1(MatrixComplexPowerReturnValue, pow, power to \c p, const std::complex<RealScalar>& p)
|
EIGEN_MATRIX_FUNCTION_1(MatrixComplexPowerReturnValue, pow, power to \c p, const std::complex<RealScalar>& p)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
EIGEN_DEVICE_FUNC MatrixBase() : Base() {}
|
EIGEN_DEFAULT_COPY_CONSTRUCTOR(MatrixBase)
|
||||||
|
EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(MatrixBase)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EIGEN_DEVICE_FUNC explicit MatrixBase(int);
|
EIGEN_DEVICE_FUNC explicit MatrixBase(int);
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,11 @@ namespace Eigen {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
template<typename ExpressionType>
|
template<typename ExpressionType>
|
||||||
struct traits<NestByValue<ExpressionType> > : public traits<ExpressionType>
|
struct traits<NestByValue<ExpressionType> > : public traits<ExpressionType>
|
||||||
{};
|
{
|
||||||
|
enum {
|
||||||
|
Flags = traits<ExpressionType>::Flags & ~NestByRefBit
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \class NestByValue
|
/** \class NestByValue
|
||||||
|
|
@ -41,57 +45,13 @@ template<typename ExpressionType> class NestByValue
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit inline NestByValue(const ExpressionType& matrix) : m_expression(matrix) {}
|
EIGEN_DEVICE_FUNC explicit inline NestByValue(const ExpressionType& matrix) : m_expression(matrix) {}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline Index rows() const { return m_expression.rows(); }
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index rows() const EIGEN_NOEXCEPT { return m_expression.rows(); }
|
||||||
EIGEN_DEVICE_FUNC inline Index cols() const { return m_expression.cols(); }
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index cols() const EIGEN_NOEXCEPT { return m_expression.cols(); }
|
||||||
EIGEN_DEVICE_FUNC inline Index outerStride() const { return m_expression.outerStride(); }
|
|
||||||
EIGEN_DEVICE_FUNC inline Index innerStride() const { return m_expression.innerStride(); }
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline const CoeffReturnType coeff(Index row, Index col) const
|
|
||||||
{
|
|
||||||
return m_expression.coeff(row, col);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index row, Index col)
|
|
||||||
{
|
|
||||||
return m_expression.const_cast_derived().coeffRef(row, col);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline const CoeffReturnType coeff(Index index) const
|
|
||||||
{
|
|
||||||
return m_expression.coeff(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index index)
|
|
||||||
{
|
|
||||||
return m_expression.const_cast_derived().coeffRef(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int LoadMode>
|
|
||||||
inline const PacketScalar packet(Index row, Index col) const
|
|
||||||
{
|
|
||||||
return m_expression.template packet<LoadMode>(row, col);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int LoadMode>
|
|
||||||
inline void writePacket(Index row, Index col, const PacketScalar& x)
|
|
||||||
{
|
|
||||||
m_expression.const_cast_derived().template writePacket<LoadMode>(row, col, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int LoadMode>
|
|
||||||
inline const PacketScalar packet(Index index) const
|
|
||||||
{
|
|
||||||
return m_expression.template packet<LoadMode>(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int LoadMode>
|
|
||||||
inline void writePacket(Index index, const PacketScalar& x)
|
|
||||||
{
|
|
||||||
m_expression.const_cast_derived().template writePacket<LoadMode>(index, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC operator const ExpressionType&() const { return m_expression; }
|
EIGEN_DEVICE_FUNC operator const ExpressionType&() const { return m_expression; }
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC const ExpressionType& nestedExpression() const { return m_expression; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const ExpressionType m_expression;
|
const ExpressionType m_expression;
|
||||||
};
|
};
|
||||||
|
|
@ -99,12 +59,27 @@ template<typename ExpressionType> class NestByValue
|
||||||
/** \returns an expression of the temporary version of *this.
|
/** \returns an expression of the temporary version of *this.
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline const NestByValue<Derived>
|
EIGEN_DEVICE_FUNC inline const NestByValue<Derived>
|
||||||
DenseBase<Derived>::nestByValue() const
|
DenseBase<Derived>::nestByValue() const
|
||||||
{
|
{
|
||||||
return NestByValue<Derived>(derived());
|
return NestByValue<Derived>(derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// Evaluator of Solve -> eval into a temporary
|
||||||
|
template<typename ArgType>
|
||||||
|
struct evaluator<NestByValue<ArgType> >
|
||||||
|
: public evaluator<ArgType>
|
||||||
|
{
|
||||||
|
typedef evaluator<ArgType> Base;
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC explicit evaluator(const NestByValue<ArgType>& xpr)
|
||||||
|
: Base(xpr.nestedExpression())
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_NESTBYVALUE_H
|
#endif // EIGEN_NESTBYVALUE_H
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ class NoAlias
|
||||||
public:
|
public:
|
||||||
typedef typename ExpressionType::Scalar Scalar;
|
typedef typename ExpressionType::Scalar Scalar;
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
explicit NoAlias(ExpressionType& expression) : m_expression(expression) {}
|
explicit NoAlias(ExpressionType& expression) : m_expression(expression) {}
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
|
|
@ -74,10 +75,10 @@ class NoAlias
|
||||||
*
|
*
|
||||||
* More precisely, noalias() allows to bypass the EvalBeforeAssignBit flag.
|
* More precisely, noalias() allows to bypass the EvalBeforeAssignBit flag.
|
||||||
* Currently, even though several expressions may alias, only product
|
* Currently, even though several expressions may alias, only product
|
||||||
* expressions have this flag. Therefore, noalias() is only usefull when
|
* expressions have this flag. Therefore, noalias() is only useful when
|
||||||
* the source expression contains a matrix product.
|
* the source expression contains a matrix product.
|
||||||
*
|
*
|
||||||
* Here are some examples where noalias is usefull:
|
* Here are some examples where noalias is useful:
|
||||||
* \code
|
* \code
|
||||||
* D.noalias() = A * B;
|
* D.noalias() = A * B;
|
||||||
* D.noalias() += A.transpose() * B;
|
* D.noalias() += A.transpose() * B;
|
||||||
|
|
@ -98,7 +99,7 @@ class NoAlias
|
||||||
* \sa class NoAlias
|
* \sa class NoAlias
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
NoAlias<Derived,MatrixBase> MatrixBase<Derived>::noalias()
|
NoAlias<Derived,MatrixBase> EIGEN_DEVICE_FUNC MatrixBase<Derived>::noalias()
|
||||||
{
|
{
|
||||||
return NoAlias<Derived, Eigen::MatrixBase >(derived());
|
return NoAlias<Derived, Eigen::MatrixBase >(derived());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,14 @@ template< typename T,
|
||||||
bool is_integer = NumTraits<T>::IsInteger>
|
bool is_integer = NumTraits<T>::IsInteger>
|
||||||
struct default_digits10_impl
|
struct default_digits10_impl
|
||||||
{
|
{
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
static int run() { return std::numeric_limits<T>::digits10; }
|
static int run() { return std::numeric_limits<T>::digits10; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct default_digits10_impl<T,false,false> // Floating point
|
struct default_digits10_impl<T,false,false> // Floating point
|
||||||
{
|
{
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
static int run() {
|
static int run() {
|
||||||
using std::log10;
|
using std::log10;
|
||||||
using std::ceil;
|
using std::ceil;
|
||||||
|
|
@ -38,11 +40,64 @@ struct default_digits10_impl<T,false,false> // Floating point
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct default_digits10_impl<T,false,true> // Integer
|
struct default_digits10_impl<T,false,true> // Integer
|
||||||
{
|
{
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
|
static int run() { return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// default implementation of digits(), based on numeric_limits if specialized,
|
||||||
|
// 0 for integer types, and log2(epsilon()) otherwise.
|
||||||
|
template< typename T,
|
||||||
|
bool use_numeric_limits = std::numeric_limits<T>::is_specialized,
|
||||||
|
bool is_integer = NumTraits<T>::IsInteger>
|
||||||
|
struct default_digits_impl
|
||||||
|
{
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
|
static int run() { return std::numeric_limits<T>::digits; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct default_digits_impl<T,false,false> // Floating point
|
||||||
|
{
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
|
static int run() {
|
||||||
|
using std::log;
|
||||||
|
using std::ceil;
|
||||||
|
typedef typename NumTraits<T>::Real Real;
|
||||||
|
return int(ceil(-log(NumTraits<Real>::epsilon())/log(static_cast<Real>(2))));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct default_digits_impl<T,false,true> // Integer
|
||||||
|
{
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
static int run() { return 0; }
|
static int run() { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
|
namespace numext {
|
||||||
|
/** \internal bit-wise cast without changing the underlying bit representation. */
|
||||||
|
|
||||||
|
// TODO: Replace by std::bit_cast (available in C++20)
|
||||||
|
template <typename Tgt, typename Src>
|
||||||
|
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Tgt bit_cast(const Src& src) {
|
||||||
|
#if EIGEN_HAS_TYPE_TRAITS
|
||||||
|
// The behaviour of memcpy is not specified for non-trivially copyable types
|
||||||
|
EIGEN_STATIC_ASSERT(std::is_trivially_copyable<Src>::value, THIS_TYPE_IS_NOT_SUPPORTED);
|
||||||
|
EIGEN_STATIC_ASSERT(std::is_trivially_copyable<Tgt>::value && std::is_default_constructible<Tgt>::value,
|
||||||
|
THIS_TYPE_IS_NOT_SUPPORTED);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EIGEN_STATIC_ASSERT(sizeof(Src) == sizeof(Tgt), THIS_TYPE_IS_NOT_SUPPORTED);
|
||||||
|
Tgt tgt;
|
||||||
|
EIGEN_USING_STD(memcpy)
|
||||||
|
memcpy(&tgt, &src, sizeof(Tgt));
|
||||||
|
return tgt;
|
||||||
|
}
|
||||||
|
} // namespace numext
|
||||||
|
|
||||||
/** \class NumTraits
|
/** \class NumTraits
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
*
|
*
|
||||||
|
|
@ -71,7 +126,7 @@ struct default_digits10_impl<T,false,true> // Integer
|
||||||
* and to \c 0 otherwise.
|
* and to \c 0 otherwise.
|
||||||
* \li Enum values ReadCost, AddCost and MulCost representing a rough estimate of the number of CPU cycles needed
|
* \li Enum values ReadCost, AddCost and MulCost representing a rough estimate of the number of CPU cycles needed
|
||||||
* to by move / add / mul instructions respectively, assuming the data is already stored in CPU registers.
|
* to by move / add / mul instructions respectively, assuming the data is already stored in CPU registers.
|
||||||
* Stay vague here. No need to do architecture-specific stuff.
|
* Stay vague here. No need to do architecture-specific stuff. If you don't know what this means, just use \c Eigen::HugeCost.
|
||||||
* \li An enum value \a IsSigned. It is equal to \c 1 if \a T is a signed type and to 0 if \a T is unsigned.
|
* \li An enum value \a IsSigned. It is equal to \c 1 if \a T is a signed type and to 0 if \a T is unsigned.
|
||||||
* \li An enum value \a RequireInitialization. It is equal to \c 1 if the constructor of the numeric type \a T must
|
* \li An enum value \a RequireInitialization. It is equal to \c 1 if the constructor of the numeric type \a T must
|
||||||
* be called, and to 0 if it is safe not to call it. Default is 0 if \a T is an arithmetic type, and 1 otherwise.
|
* be called, and to 0 if it is safe not to call it. Default is 0 if \a T is an arithmetic type, and 1 otherwise.
|
||||||
|
|
@ -80,9 +135,18 @@ struct default_digits10_impl<T,false,true> // Integer
|
||||||
* \li A dummy_precision() function returning a weak epsilon value. It is mainly used as a default
|
* \li A dummy_precision() function returning a weak epsilon value. It is mainly used as a default
|
||||||
* value by the fuzzy comparison operators.
|
* value by the fuzzy comparison operators.
|
||||||
* \li highest() and lowest() functions returning the highest and lowest possible values respectively.
|
* \li highest() and lowest() functions returning the highest and lowest possible values respectively.
|
||||||
|
* \li digits() function returning the number of radix digits (non-sign digits for integers, mantissa for floating-point). This is
|
||||||
|
* the analogue of <a href="http://en.cppreference.com/w/cpp/types/numeric_limits/digits">std::numeric_limits<T>::digits</a>
|
||||||
|
* which is used as the default implementation if specialized.
|
||||||
* \li digits10() function returning the number of decimal digits that can be represented without change. This is
|
* \li digits10() function returning the number of decimal digits that can be represented without change. This is
|
||||||
* the analogue of <a href="http://en.cppreference.com/w/cpp/types/numeric_limits/digits10">std::numeric_limits<T>::digits10</a>
|
* the analogue of <a href="http://en.cppreference.com/w/cpp/types/numeric_limits/digits10">std::numeric_limits<T>::digits10</a>
|
||||||
* which is used as the default implementation if specialized.
|
* which is used as the default implementation if specialized.
|
||||||
|
* \li min_exponent() and max_exponent() functions returning the highest and lowest possible values, respectively,
|
||||||
|
* such that the radix raised to the power exponent-1 is a normalized floating-point number. These are equivalent to
|
||||||
|
* <a href="http://en.cppreference.com/w/cpp/types/numeric_limits/min_exponent">std::numeric_limits<T>::min_exponent</a>/
|
||||||
|
* <a href="http://en.cppreference.com/w/cpp/types/numeric_limits/max_exponent">std::numeric_limits<T>::max_exponent</a>.
|
||||||
|
* \li infinity() function returning a representation of positive infinity, if available.
|
||||||
|
* \li quiet_NaN function returning a non-signaling "not-a-number", if available.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template<typename T> struct GenericNumTraits
|
template<typename T> struct GenericNumTraits
|
||||||
|
|
@ -106,42 +170,60 @@ template<typename T> struct GenericNumTraits
|
||||||
typedef T Nested;
|
typedef T Nested;
|
||||||
typedef T Literal;
|
typedef T Literal;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
static inline Real epsilon()
|
static inline Real epsilon()
|
||||||
{
|
{
|
||||||
return numext::numeric_limits<T>::epsilon();
|
return numext::numeric_limits<T>::epsilon();
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
static inline int digits10()
|
static inline int digits10()
|
||||||
{
|
{
|
||||||
return internal::default_digits10_impl<T>::run();
|
return internal::default_digits10_impl<T>::run();
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
|
static inline int digits()
|
||||||
|
{
|
||||||
|
return internal::default_digits_impl<T>::run();
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
|
static inline int min_exponent()
|
||||||
|
{
|
||||||
|
return numext::numeric_limits<T>::min_exponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
|
static inline int max_exponent()
|
||||||
|
{
|
||||||
|
return numext::numeric_limits<T>::max_exponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
static inline Real dummy_precision()
|
static inline Real dummy_precision()
|
||||||
{
|
{
|
||||||
// make sure to override this for floating-point types
|
// make sure to override this for floating-point types
|
||||||
return Real(0);
|
return Real(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static inline T highest() {
|
static inline T highest() {
|
||||||
return (numext::numeric_limits<T>::max)();
|
return (numext::numeric_limits<T>::max)();
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
static inline T lowest() {
|
static inline T lowest() {
|
||||||
return IsInteger ? (numext::numeric_limits<T>::min)() : (-(numext::numeric_limits<T>::max)());
|
return IsInteger ? (numext::numeric_limits<T>::min)()
|
||||||
|
: static_cast<T>(-(numext::numeric_limits<T>::max)());
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
static inline T infinity() {
|
static inline T infinity() {
|
||||||
return numext::numeric_limits<T>::infinity();
|
return numext::numeric_limits<T>::infinity();
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
static inline T quiet_NaN() {
|
static inline T quiet_NaN() {
|
||||||
return numext::numeric_limits<T>::quiet_NaN();
|
return numext::numeric_limits<T>::quiet_NaN();
|
||||||
}
|
}
|
||||||
|
|
@ -153,19 +235,20 @@ template<typename T> struct NumTraits : GenericNumTraits<T>
|
||||||
template<> struct NumTraits<float>
|
template<> struct NumTraits<float>
|
||||||
: GenericNumTraits<float>
|
: GenericNumTraits<float>
|
||||||
{
|
{
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
static inline float dummy_precision() { return 1e-5f; }
|
static inline float dummy_precision() { return 1e-5f; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> struct NumTraits<double> : GenericNumTraits<double>
|
template<> struct NumTraits<double> : GenericNumTraits<double>
|
||||||
{
|
{
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
static inline double dummy_precision() { return 1e-12; }
|
static inline double dummy_precision() { return 1e-12; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> struct NumTraits<long double>
|
template<> struct NumTraits<long double>
|
||||||
: GenericNumTraits<long double>
|
: GenericNumTraits<long double>
|
||||||
{
|
{
|
||||||
|
EIGEN_CONSTEXPR
|
||||||
static inline long double dummy_precision() { return 1e-15l; }
|
static inline long double dummy_precision() { return 1e-15l; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -182,11 +265,11 @@ template<typename _Real> struct NumTraits<std::complex<_Real> >
|
||||||
MulCost = 4 * NumTraits<Real>::MulCost + 2 * NumTraits<Real>::AddCost
|
MulCost = 4 * NumTraits<Real>::MulCost + 2 * NumTraits<Real>::AddCost
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
static inline Real epsilon() { return NumTraits<Real>::epsilon(); }
|
static inline Real epsilon() { return NumTraits<Real>::epsilon(); }
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
static inline Real dummy_precision() { return NumTraits<Real>::dummy_precision(); }
|
static inline Real dummy_precision() { return NumTraits<Real>::dummy_precision(); }
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
static inline int digits10() { return NumTraits<Real>::digits10(); }
|
static inline int digits10() { return NumTraits<Real>::digits10(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -206,16 +289,17 @@ struct NumTraits<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
|
||||||
IsInteger = NumTraits<Scalar>::IsInteger,
|
IsInteger = NumTraits<Scalar>::IsInteger,
|
||||||
IsSigned = NumTraits<Scalar>::IsSigned,
|
IsSigned = NumTraits<Scalar>::IsSigned,
|
||||||
RequireInitialization = 1,
|
RequireInitialization = 1,
|
||||||
ReadCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::ReadCost,
|
ReadCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * int(NumTraits<Scalar>::ReadCost),
|
||||||
AddCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::AddCost,
|
AddCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * int(NumTraits<Scalar>::AddCost),
|
||||||
MulCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::MulCost
|
MulCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * int(NumTraits<Scalar>::MulCost)
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
static inline RealScalar epsilon() { return NumTraits<RealScalar>::epsilon(); }
|
static inline RealScalar epsilon() { return NumTraits<RealScalar>::epsilon(); }
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
static inline RealScalar dummy_precision() { return NumTraits<RealScalar>::dummy_precision(); }
|
static inline RealScalar dummy_precision() { return NumTraits<RealScalar>::dummy_precision(); }
|
||||||
|
|
||||||
|
EIGEN_CONSTEXPR
|
||||||
static inline int digits10() { return NumTraits<Scalar>::digits10(); }
|
static inline int digits10() { return NumTraits<Scalar>::digits10(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -229,6 +313,7 @@ template<> struct NumTraits<std::string>
|
||||||
MulCost = HugeCost
|
MulCost = HugeCost
|
||||||
};
|
};
|
||||||
|
|
||||||
|
EIGEN_CONSTEXPR
|
||||||
static inline int digits10() { return 0; }
|
static inline int digits10() { return 0; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -243,6 +328,8 @@ private:
|
||||||
// Empty specialization for void to allow template specialization based on NumTraits<T>::Real with T==void and SFINAE.
|
// Empty specialization for void to allow template specialization based on NumTraits<T>::Real with T==void and SFINAE.
|
||||||
template<> struct NumTraits<void> {};
|
template<> struct NumTraits<void> {};
|
||||||
|
|
||||||
|
template<> struct NumTraits<bool> : GenericNumTraits<bool> {};
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_NUMTRAITS_H
|
#endif // EIGEN_NUMTRAITS_H
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,232 @@
|
||||||
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
|
// for linear algebra.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2011-2018 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the Mozilla
|
||||||
|
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||||
|
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
#ifndef EIGEN_PARTIALREDUX_H
|
||||||
|
#define EIGEN_PARTIALREDUX_H
|
||||||
|
|
||||||
|
namespace Eigen {
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
*
|
||||||
|
* This file provides evaluators for partial reductions.
|
||||||
|
* There are two modes:
|
||||||
|
*
|
||||||
|
* - scalar path: simply calls the respective function on the column or row.
|
||||||
|
* -> nothing special here, all the tricky part is handled by the return
|
||||||
|
* types of VectorwiseOp's members. They embed the functor calling the
|
||||||
|
* respective DenseBase's member function.
|
||||||
|
*
|
||||||
|
* - vectorized path: implements a packet-wise reductions followed by
|
||||||
|
* some (optional) processing of the outcome, e.g., division by n for mean.
|
||||||
|
*
|
||||||
|
* For the vectorized path let's observe that the packet-size and outer-unrolling
|
||||||
|
* are both decided by the assignement logic. So all we have to do is to decide
|
||||||
|
* on the inner unrolling.
|
||||||
|
*
|
||||||
|
* For the unrolling, we can reuse "internal::redux_vec_unroller" from Redux.h,
|
||||||
|
* but be need to be careful to specify correct increment.
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* logic deciding a strategy for unrolling of vectorized paths */
|
||||||
|
template<typename Func, typename Evaluator>
|
||||||
|
struct packetwise_redux_traits
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
OuterSize = int(Evaluator::IsRowMajor) ? Evaluator::RowsAtCompileTime : Evaluator::ColsAtCompileTime,
|
||||||
|
Cost = OuterSize == Dynamic ? HugeCost
|
||||||
|
: OuterSize * Evaluator::CoeffReadCost + (OuterSize-1) * functor_traits<Func>::Cost,
|
||||||
|
Unrolling = Cost <= EIGEN_UNROLLING_LIMIT ? CompleteUnrolling : NoUnrolling
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Value to be returned when size==0 , by default let's return 0 */
|
||||||
|
template<typename PacketType,typename Func>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
PacketType packetwise_redux_empty_value(const Func& ) { return pset1<PacketType>(0); }
|
||||||
|
|
||||||
|
/* For products the default is 1 */
|
||||||
|
template<typename PacketType,typename Scalar>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
PacketType packetwise_redux_empty_value(const scalar_product_op<Scalar,Scalar>& ) { return pset1<PacketType>(1); }
|
||||||
|
|
||||||
|
/* Perform the actual reduction */
|
||||||
|
template<typename Func, typename Evaluator,
|
||||||
|
int Unrolling = packetwise_redux_traits<Func, Evaluator>::Unrolling
|
||||||
|
>
|
||||||
|
struct packetwise_redux_impl;
|
||||||
|
|
||||||
|
/* Perform the actual reduction with unrolling */
|
||||||
|
template<typename Func, typename Evaluator>
|
||||||
|
struct packetwise_redux_impl<Func, Evaluator, CompleteUnrolling>
|
||||||
|
{
|
||||||
|
typedef redux_novec_unroller<Func,Evaluator, 0, Evaluator::SizeAtCompileTime> Base;
|
||||||
|
typedef typename Evaluator::Scalar Scalar;
|
||||||
|
|
||||||
|
template<typename PacketType>
|
||||||
|
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE
|
||||||
|
PacketType run(const Evaluator &eval, const Func& func, Index /*size*/)
|
||||||
|
{
|
||||||
|
return redux_vec_unroller<Func, Evaluator, 0, packetwise_redux_traits<Func, Evaluator>::OuterSize>::template run<PacketType>(eval,func);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Add a specialization of redux_vec_unroller for size==0 at compiletime.
|
||||||
|
* This specialization is not required for general reductions, which is
|
||||||
|
* why it is defined here.
|
||||||
|
*/
|
||||||
|
template<typename Func, typename Evaluator, int Start>
|
||||||
|
struct redux_vec_unroller<Func, Evaluator, Start, 0>
|
||||||
|
{
|
||||||
|
template<typename PacketType>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
static EIGEN_STRONG_INLINE PacketType run(const Evaluator &, const Func& f)
|
||||||
|
{
|
||||||
|
return packetwise_redux_empty_value<PacketType>(f);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Perform the actual reduction for dynamic sizes */
|
||||||
|
template<typename Func, typename Evaluator>
|
||||||
|
struct packetwise_redux_impl<Func, Evaluator, NoUnrolling>
|
||||||
|
{
|
||||||
|
typedef typename Evaluator::Scalar Scalar;
|
||||||
|
typedef typename redux_traits<Func, Evaluator>::PacketType PacketScalar;
|
||||||
|
|
||||||
|
template<typename PacketType>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
static PacketType run(const Evaluator &eval, const Func& func, Index size)
|
||||||
|
{
|
||||||
|
if(size==0)
|
||||||
|
return packetwise_redux_empty_value<PacketType>(func);
|
||||||
|
|
||||||
|
const Index size4 = (size-1)&(~3);
|
||||||
|
PacketType p = eval.template packetByOuterInner<Unaligned,PacketType>(0,0);
|
||||||
|
Index i = 1;
|
||||||
|
// This loop is optimized for instruction pipelining:
|
||||||
|
// - each iteration generates two independent instructions
|
||||||
|
// - thanks to branch prediction and out-of-order execution we have independent instructions across loops
|
||||||
|
for(; i<size4; i+=4)
|
||||||
|
p = func.packetOp(p,
|
||||||
|
func.packetOp(
|
||||||
|
func.packetOp(eval.template packetByOuterInner<Unaligned,PacketType>(i+0,0),eval.template packetByOuterInner<Unaligned,PacketType>(i+1,0)),
|
||||||
|
func.packetOp(eval.template packetByOuterInner<Unaligned,PacketType>(i+2,0),eval.template packetByOuterInner<Unaligned,PacketType>(i+3,0))));
|
||||||
|
for(; i<size; ++i)
|
||||||
|
p = func.packetOp(p, eval.template packetByOuterInner<Unaligned,PacketType>(i,0));
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template< typename ArgType, typename MemberOp, int Direction>
|
||||||
|
struct evaluator<PartialReduxExpr<ArgType, MemberOp, Direction> >
|
||||||
|
: evaluator_base<PartialReduxExpr<ArgType, MemberOp, Direction> >
|
||||||
|
{
|
||||||
|
typedef PartialReduxExpr<ArgType, MemberOp, Direction> XprType;
|
||||||
|
typedef typename internal::nested_eval<ArgType,1>::type ArgTypeNested;
|
||||||
|
typedef typename internal::add_const_on_value_type<ArgTypeNested>::type ConstArgTypeNested;
|
||||||
|
typedef typename internal::remove_all<ArgTypeNested>::type ArgTypeNestedCleaned;
|
||||||
|
typedef typename ArgType::Scalar InputScalar;
|
||||||
|
typedef typename XprType::Scalar Scalar;
|
||||||
|
enum {
|
||||||
|
TraversalSize = Direction==int(Vertical) ? int(ArgType::RowsAtCompileTime) : int(ArgType::ColsAtCompileTime)
|
||||||
|
};
|
||||||
|
typedef typename MemberOp::template Cost<int(TraversalSize)> CostOpType;
|
||||||
|
enum {
|
||||||
|
CoeffReadCost = TraversalSize==Dynamic ? HugeCost
|
||||||
|
: TraversalSize==0 ? 1
|
||||||
|
: int(TraversalSize) * int(evaluator<ArgType>::CoeffReadCost) + int(CostOpType::value),
|
||||||
|
|
||||||
|
_ArgFlags = evaluator<ArgType>::Flags,
|
||||||
|
|
||||||
|
_Vectorizable = bool(int(_ArgFlags)&PacketAccessBit)
|
||||||
|
&& bool(MemberOp::Vectorizable)
|
||||||
|
&& (Direction==int(Vertical) ? bool(_ArgFlags&RowMajorBit) : (_ArgFlags&RowMajorBit)==0)
|
||||||
|
&& (TraversalSize!=0),
|
||||||
|
|
||||||
|
Flags = (traits<XprType>::Flags&RowMajorBit)
|
||||||
|
| (evaluator<ArgType>::Flags&(HereditaryBits&(~RowMajorBit)))
|
||||||
|
| (_Vectorizable ? PacketAccessBit : 0)
|
||||||
|
| LinearAccessBit,
|
||||||
|
|
||||||
|
Alignment = 0 // FIXME this will need to be improved once PartialReduxExpr is vectorized
|
||||||
|
};
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC explicit evaluator(const XprType xpr)
|
||||||
|
: m_arg(xpr.nestedExpression()), m_functor(xpr.functor())
|
||||||
|
{
|
||||||
|
EIGEN_INTERNAL_CHECK_COST_VALUE(TraversalSize==Dynamic ? HugeCost : (TraversalSize==0 ? 1 : int(CostOpType::value)));
|
||||||
|
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
const Scalar coeff(Index i, Index j) const
|
||||||
|
{
|
||||||
|
return coeff(Direction==Vertical ? j : i);
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
const Scalar coeff(Index index) const
|
||||||
|
{
|
||||||
|
return m_functor(m_arg.template subVector<DirectionType(Direction)>(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode,typename PacketType>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
PacketType packet(Index i, Index j) const
|
||||||
|
{
|
||||||
|
return packet<LoadMode,PacketType>(Direction==Vertical ? j : i);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode,typename PacketType>
|
||||||
|
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
|
||||||
|
PacketType packet(Index idx) const
|
||||||
|
{
|
||||||
|
enum { PacketSize = internal::unpacket_traits<PacketType>::size };
|
||||||
|
typedef Block<const ArgTypeNestedCleaned,
|
||||||
|
Direction==Vertical ? int(ArgType::RowsAtCompileTime) : int(PacketSize),
|
||||||
|
Direction==Vertical ? int(PacketSize) : int(ArgType::ColsAtCompileTime),
|
||||||
|
true /* InnerPanel */> PanelType;
|
||||||
|
|
||||||
|
PanelType panel(m_arg,
|
||||||
|
Direction==Vertical ? 0 : idx,
|
||||||
|
Direction==Vertical ? idx : 0,
|
||||||
|
Direction==Vertical ? m_arg.rows() : Index(PacketSize),
|
||||||
|
Direction==Vertical ? Index(PacketSize) : m_arg.cols());
|
||||||
|
|
||||||
|
// FIXME
|
||||||
|
// See bug 1612, currently if PacketSize==1 (i.e. complex<double> with 128bits registers) then the storage-order of panel get reversed
|
||||||
|
// and methods like packetByOuterInner do not make sense anymore in this context.
|
||||||
|
// So let's just by pass "vectorization" in this case:
|
||||||
|
if(PacketSize==1)
|
||||||
|
return internal::pset1<PacketType>(coeff(idx));
|
||||||
|
|
||||||
|
typedef typename internal::redux_evaluator<PanelType> PanelEvaluator;
|
||||||
|
PanelEvaluator panel_eval(panel);
|
||||||
|
typedef typename MemberOp::BinaryOp BinaryOp;
|
||||||
|
PacketType p = internal::packetwise_redux_impl<BinaryOp,PanelEvaluator>::template run<PacketType>(panel_eval,m_functor.binaryFunc(),m_arg.outerSize());
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ConstArgTypeNested m_arg;
|
||||||
|
const MemberOp m_functor;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace internal
|
||||||
|
|
||||||
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
#endif // EIGEN_PARTIALREDUX_H
|
||||||
|
|
@ -87,25 +87,14 @@ class PermutationBase : public EigenBase<Derived>
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
/** This is a special case of the templated operator=. Its purpose is to
|
|
||||||
* prevent a default operator= from hiding the templated operator=.
|
|
||||||
*/
|
|
||||||
Derived& operator=(const PermutationBase& other)
|
|
||||||
{
|
|
||||||
indices() = other.indices();
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \returns the number of rows */
|
/** \returns the number of rows */
|
||||||
inline Index rows() const { return Index(indices().size()); }
|
inline EIGEN_DEVICE_FUNC Index rows() const { return Index(indices().size()); }
|
||||||
|
|
||||||
/** \returns the number of columns */
|
/** \returns the number of columns */
|
||||||
inline Index cols() const { return Index(indices().size()); }
|
inline EIGEN_DEVICE_FUNC Index cols() const { return Index(indices().size()); }
|
||||||
|
|
||||||
/** \returns the size of a side of the respective square matrix, i.e., the number of indices */
|
/** \returns the size of a side of the respective square matrix, i.e., the number of indices */
|
||||||
inline Index size() const { return Index(indices().size()); }
|
inline EIGEN_DEVICE_FUNC Index size() const { return Index(indices().size()); }
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
template<typename DenseDerived>
|
template<typename DenseDerived>
|
||||||
|
|
@ -333,12 +322,6 @@ class PermutationMatrix : public PermutationBase<PermutationMatrix<SizeAtCompile
|
||||||
inline PermutationMatrix(const PermutationBase<OtherDerived>& other)
|
inline PermutationMatrix(const PermutationBase<OtherDerived>& other)
|
||||||
: m_indices(other.indices()) {}
|
: m_indices(other.indices()) {}
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
/** Standard copy constructor. Defined only to prevent a default copy constructor
|
|
||||||
* from hiding the other templated constructor */
|
|
||||||
inline PermutationMatrix(const PermutationMatrix& other) : m_indices(other.indices()) {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Generic constructor from expression of the indices. The indices
|
/** Generic constructor from expression of the indices. The indices
|
||||||
* array has the meaning that the permutations sends each integer i to indices[i].
|
* array has the meaning that the permutations sends each integer i to indices[i].
|
||||||
*
|
*
|
||||||
|
|
@ -373,17 +356,6 @@ class PermutationMatrix : public PermutationBase<PermutationMatrix<SizeAtCompile
|
||||||
return Base::operator=(tr.derived());
|
return Base::operator=(tr.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
/** This is a special case of the templated operator=. Its purpose is to
|
|
||||||
* prevent a default operator= from hiding the templated operator=.
|
|
||||||
*/
|
|
||||||
PermutationMatrix& operator=(const PermutationMatrix& other)
|
|
||||||
{
|
|
||||||
m_indices = other.m_indices;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** const version of indices(). */
|
/** const version of indices(). */
|
||||||
const IndicesType& indices() const { return m_indices; }
|
const IndicesType& indices() const { return m_indices; }
|
||||||
/** \returns a reference to the stored array representing the permutation. */
|
/** \returns a reference to the stored array representing the permutation. */
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,10 @@
|
||||||
|
|
||||||
#if defined(EIGEN_INITIALIZE_MATRICES_BY_ZERO)
|
#if defined(EIGEN_INITIALIZE_MATRICES_BY_ZERO)
|
||||||
# define EIGEN_INITIALIZE_COEFFS
|
# define EIGEN_INITIALIZE_COEFFS
|
||||||
# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=Scalar(0);
|
# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED for(Index i=0;i<base().size();++i) coeffRef(i)=Scalar(0);
|
||||||
#elif defined(EIGEN_INITIALIZE_MATRICES_BY_NAN)
|
#elif defined(EIGEN_INITIALIZE_MATRICES_BY_NAN)
|
||||||
# define EIGEN_INITIALIZE_COEFFS
|
# define EIGEN_INITIALIZE_COEFFS
|
||||||
# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=std::numeric_limits<Scalar>::quiet_NaN();
|
# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED for(Index i=0;i<base().size();++i) coeffRef(i)=std::numeric_limits<Scalar>::quiet_NaN();
|
||||||
#else
|
#else
|
||||||
# undef EIGEN_INITIALIZE_COEFFS
|
# undef EIGEN_INITIALIZE_COEFFS
|
||||||
# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
|
# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
|
||||||
|
|
@ -118,16 +118,8 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||||
using Base::IsVectorAtCompileTime;
|
using Base::IsVectorAtCompileTime;
|
||||||
using Base::Flags;
|
using Base::Flags;
|
||||||
|
|
||||||
template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map;
|
|
||||||
friend class Eigen::Map<Derived, Unaligned>;
|
|
||||||
typedef Eigen::Map<Derived, Unaligned> MapType;
|
typedef Eigen::Map<Derived, Unaligned> MapType;
|
||||||
friend class Eigen::Map<const Derived, Unaligned>;
|
|
||||||
typedef const Eigen::Map<const Derived, Unaligned> ConstMapType;
|
typedef const Eigen::Map<const Derived, Unaligned> ConstMapType;
|
||||||
#if EIGEN_MAX_ALIGN_BYTES>0
|
|
||||||
// for EIGEN_MAX_ALIGN_BYTES==0, AlignedMax==Unaligned, and many compilers generate warnings for friend-ing a class twice.
|
|
||||||
friend class Eigen::Map<Derived, AlignedMax>;
|
|
||||||
friend class Eigen::Map<const Derived, AlignedMax>;
|
|
||||||
#endif
|
|
||||||
typedef Eigen::Map<Derived, AlignedMax> AlignedMapType;
|
typedef Eigen::Map<Derived, AlignedMax> AlignedMapType;
|
||||||
typedef const Eigen::Map<const Derived, AlignedMax> ConstAlignedMapType;
|
typedef const Eigen::Map<const Derived, AlignedMax> ConstAlignedMapType;
|
||||||
template<typename StrideType> struct StridedMapType { typedef Eigen::Map<Derived, Unaligned, StrideType> type; };
|
template<typename StrideType> struct StridedMapType { typedef Eigen::Map<Derived, Unaligned, StrideType> type; };
|
||||||
|
|
@ -147,10 +139,10 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const Base& base() const { return *static_cast<const Base*>(this); }
|
const Base& base() const { return *static_cast<const Base*>(this); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); }
|
Index rows() const EIGEN_NOEXCEPT { return m_storage.rows(); }
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); }
|
Index cols() const EIGEN_NOEXCEPT { return m_storage.cols(); }
|
||||||
|
|
||||||
/** This is an overloaded version of DenseCoeffsBase<Derived,ReadOnlyAccessors>::coeff(Index,Index) const
|
/** This is an overloaded version of DenseCoeffsBase<Derived,ReadOnlyAccessors>::coeff(Index,Index) const
|
||||||
* provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts.
|
* provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts.
|
||||||
|
|
@ -508,8 +500,8 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
PlainObjectBase& operator=(PlainObjectBase&& other) EIGEN_NOEXCEPT
|
PlainObjectBase& operator=(PlainObjectBase&& other) EIGEN_NOEXCEPT
|
||||||
{
|
{
|
||||||
using std::swap;
|
_check_template_params();
|
||||||
swap(m_storage, other.m_storage);
|
m_storage = std::move(other.m_storage);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -526,6 +518,71 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||||
// EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
|
// EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if EIGEN_HAS_CXX11
|
||||||
|
/** \brief Construct a row of column vector with fixed size from an arbitrary number of coefficients. \cpp11
|
||||||
|
*
|
||||||
|
* \only_for_vectors
|
||||||
|
*
|
||||||
|
* This constructor is for 1D array or vectors with more than 4 coefficients.
|
||||||
|
* There exists C++98 analogue constructors for fixed-size array/vector having 1, 2, 3, or 4 coefficients.
|
||||||
|
*
|
||||||
|
* \warning To construct a column (resp. row) vector of fixed length, the number of values passed to this
|
||||||
|
* constructor must match the the fixed number of rows (resp. columns) of \c *this.
|
||||||
|
*/
|
||||||
|
template <typename... ArgTypes>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
PlainObjectBase(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args)
|
||||||
|
: m_storage()
|
||||||
|
{
|
||||||
|
_check_template_params();
|
||||||
|
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, sizeof...(args) + 4);
|
||||||
|
m_storage.data()[0] = a0;
|
||||||
|
m_storage.data()[1] = a1;
|
||||||
|
m_storage.data()[2] = a2;
|
||||||
|
m_storage.data()[3] = a3;
|
||||||
|
Index i = 4;
|
||||||
|
auto x = {(m_storage.data()[i++] = args, 0)...};
|
||||||
|
static_cast<void>(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief Constructs a Matrix or Array and initializes it by elements given by an initializer list of initializer
|
||||||
|
* lists \cpp11
|
||||||
|
*/
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
explicit EIGEN_STRONG_INLINE PlainObjectBase(const std::initializer_list<std::initializer_list<Scalar>>& list)
|
||||||
|
: m_storage()
|
||||||
|
{
|
||||||
|
_check_template_params();
|
||||||
|
|
||||||
|
size_t list_size = 0;
|
||||||
|
if (list.begin() != list.end()) {
|
||||||
|
list_size = list.begin()->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is to allow syntax like VectorXi {{1, 2, 3, 4}}
|
||||||
|
if (ColsAtCompileTime == 1 && list.size() == 1) {
|
||||||
|
eigen_assert(list_size == static_cast<size_t>(RowsAtCompileTime) || RowsAtCompileTime == Dynamic);
|
||||||
|
resize(list_size, ColsAtCompileTime);
|
||||||
|
std::copy(list.begin()->begin(), list.begin()->end(), m_storage.data());
|
||||||
|
} else {
|
||||||
|
eigen_assert(list.size() == static_cast<size_t>(RowsAtCompileTime) || RowsAtCompileTime == Dynamic);
|
||||||
|
eigen_assert(list_size == static_cast<size_t>(ColsAtCompileTime) || ColsAtCompileTime == Dynamic);
|
||||||
|
resize(list.size(), list_size);
|
||||||
|
|
||||||
|
Index row_index = 0;
|
||||||
|
for (const std::initializer_list<Scalar>& row : list) {
|
||||||
|
eigen_assert(list_size == row.size());
|
||||||
|
Index col_index = 0;
|
||||||
|
for (const Scalar& e : row) {
|
||||||
|
coeffRef(row_index, col_index) = e;
|
||||||
|
++col_index;
|
||||||
|
}
|
||||||
|
++row_index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // end EIGEN_HAS_CXX11
|
||||||
|
|
||||||
/** \sa PlainObjectBase::operator=(const EigenBase<OtherDerived>&) */
|
/** \sa PlainObjectBase::operator=(const EigenBase<OtherDerived>&) */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
|
|
@ -652,18 +709,26 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||||
using Base::setConstant;
|
using Base::setConstant;
|
||||||
EIGEN_DEVICE_FUNC Derived& setConstant(Index size, const Scalar& val);
|
EIGEN_DEVICE_FUNC Derived& setConstant(Index size, const Scalar& val);
|
||||||
EIGEN_DEVICE_FUNC Derived& setConstant(Index rows, Index cols, const Scalar& val);
|
EIGEN_DEVICE_FUNC Derived& setConstant(Index rows, Index cols, const Scalar& val);
|
||||||
|
EIGEN_DEVICE_FUNC Derived& setConstant(NoChange_t, Index cols, const Scalar& val);
|
||||||
|
EIGEN_DEVICE_FUNC Derived& setConstant(Index rows, NoChange_t, const Scalar& val);
|
||||||
|
|
||||||
using Base::setZero;
|
using Base::setZero;
|
||||||
EIGEN_DEVICE_FUNC Derived& setZero(Index size);
|
EIGEN_DEVICE_FUNC Derived& setZero(Index size);
|
||||||
EIGEN_DEVICE_FUNC Derived& setZero(Index rows, Index cols);
|
EIGEN_DEVICE_FUNC Derived& setZero(Index rows, Index cols);
|
||||||
|
EIGEN_DEVICE_FUNC Derived& setZero(NoChange_t, Index cols);
|
||||||
|
EIGEN_DEVICE_FUNC Derived& setZero(Index rows, NoChange_t);
|
||||||
|
|
||||||
using Base::setOnes;
|
using Base::setOnes;
|
||||||
EIGEN_DEVICE_FUNC Derived& setOnes(Index size);
|
EIGEN_DEVICE_FUNC Derived& setOnes(Index size);
|
||||||
EIGEN_DEVICE_FUNC Derived& setOnes(Index rows, Index cols);
|
EIGEN_DEVICE_FUNC Derived& setOnes(Index rows, Index cols);
|
||||||
|
EIGEN_DEVICE_FUNC Derived& setOnes(NoChange_t, Index cols);
|
||||||
|
EIGEN_DEVICE_FUNC Derived& setOnes(Index rows, NoChange_t);
|
||||||
|
|
||||||
using Base::setRandom;
|
using Base::setRandom;
|
||||||
Derived& setRandom(Index size);
|
Derived& setRandom(Index size);
|
||||||
Derived& setRandom(Index rows, Index cols);
|
Derived& setRandom(Index rows, Index cols);
|
||||||
|
Derived& setRandom(NoChange_t, Index cols);
|
||||||
|
Derived& setRandom(Index rows, NoChange_t);
|
||||||
|
|
||||||
#ifdef EIGEN_PLAINOBJECTBASE_PLUGIN
|
#ifdef EIGEN_PLAINOBJECTBASE_PLUGIN
|
||||||
#include EIGEN_PLAINOBJECTBASE_PLUGIN
|
#include EIGEN_PLAINOBJECTBASE_PLUGIN
|
||||||
|
|
@ -705,7 +770,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||||
*
|
*
|
||||||
* \internal
|
* \internal
|
||||||
*/
|
*/
|
||||||
// aliasing is dealt once in internall::call_assignment
|
// aliasing is dealt once in internal::call_assignment
|
||||||
// so at this stage we have to assume aliasing... and resising has to be done later.
|
// so at this stage we have to assume aliasing... and resising has to be done later.
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
|
|
@ -737,8 +802,10 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0)
|
EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT(bool(NumTraits<T0>::IsInteger) &&
|
const bool t0_is_integer_alike = internal::is_valid_index_type<T0>::value;
|
||||||
bool(NumTraits<T1>::IsInteger),
|
const bool t1_is_integer_alike = internal::is_valid_index_type<T1>::value;
|
||||||
|
EIGEN_STATIC_ASSERT(t0_is_integer_alike &&
|
||||||
|
t1_is_integer_alike,
|
||||||
FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
|
FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
|
||||||
resize(rows,cols);
|
resize(rows,cols);
|
||||||
}
|
}
|
||||||
|
|
@ -773,14 +840,14 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||||
&& ((!internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value || Base::SizeAtCompileTime==Dynamic)),T>::type* = 0)
|
&& ((!internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value || Base::SizeAtCompileTime==Dynamic)),T>::type* = 0)
|
||||||
{
|
{
|
||||||
// NOTE MSVC 2008 complains if we directly put bool(NumTraits<T>::IsInteger) as the EIGEN_STATIC_ASSERT argument.
|
// NOTE MSVC 2008 complains if we directly put bool(NumTraits<T>::IsInteger) as the EIGEN_STATIC_ASSERT argument.
|
||||||
const bool is_integer = NumTraits<T>::IsInteger;
|
const bool is_integer_alike = internal::is_valid_index_type<T>::value;
|
||||||
EIGEN_UNUSED_VARIABLE(is_integer);
|
EIGEN_UNUSED_VARIABLE(is_integer_alike);
|
||||||
EIGEN_STATIC_ASSERT(is_integer,
|
EIGEN_STATIC_ASSERT(is_integer_alike,
|
||||||
FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
|
FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
|
||||||
resize(size);
|
resize(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have a 1x1 matrix/array => the argument is interpreted as the value of the unique coefficient (case where scalar type can be implicitely converted)
|
// We have a 1x1 matrix/array => the argument is interpreted as the value of the unique coefficient (case where scalar type can be implicitly converted)
|
||||||
template<typename T>
|
template<typename T>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
EIGEN_STRONG_INLINE void _init1(const Scalar& val0, typename internal::enable_if<Base::SizeAtCompileTime==1 && internal::is_convertible<T, Scalar>::value,T>::type* = 0)
|
EIGEN_STRONG_INLINE void _init1(const Scalar& val0, typename internal::enable_if<Base::SizeAtCompileTime==1 && internal::is_convertible<T, Scalar>::value,T>::type* = 0)
|
||||||
|
|
@ -882,7 +949,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||||
* of same type it is enough to swap the data pointers.
|
* of same type it is enough to swap the data pointers.
|
||||||
*/
|
*/
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
void swap(DenseBase<OtherDerived> & other)
|
void swap(DenseBase<OtherDerived> & other)
|
||||||
{
|
{
|
||||||
enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic };
|
enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic };
|
||||||
|
|
@ -893,15 +960,15 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||||
* \brief const version forwarded to DenseBase::swap
|
* \brief const version forwarded to DenseBase::swap
|
||||||
*/
|
*/
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
void swap(DenseBase<OtherDerived> const & other)
|
void swap(DenseBase<OtherDerived> const & other)
|
||||||
{ Base::swap(other.derived()); }
|
{ Base::swap(other.derived()); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
static EIGEN_STRONG_INLINE void _check_template_params()
|
static EIGEN_STRONG_INLINE void _check_template_params()
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor)
|
EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (int(Options)&RowMajor)==RowMajor)
|
||||||
&& EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0)
|
&& EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (int(Options)&RowMajor)==0)
|
||||||
&& ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0))
|
&& ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0))
|
||||||
&& ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0))
|
&& ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0))
|
||||||
&& ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0))
|
&& ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0))
|
||||||
|
|
@ -913,6 +980,17 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||||
}
|
}
|
||||||
|
|
||||||
enum { IsPlainObjectBase = 1 };
|
enum { IsPlainObjectBase = 1 };
|
||||||
|
#endif
|
||||||
|
public:
|
||||||
|
// These apparently need to be down here for nvcc+icc to prevent duplicate
|
||||||
|
// Map symbol.
|
||||||
|
template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map;
|
||||||
|
friend class Eigen::Map<Derived, Unaligned>;
|
||||||
|
friend class Eigen::Map<const Derived, Unaligned>;
|
||||||
|
#if EIGEN_MAX_ALIGN_BYTES>0
|
||||||
|
// for EIGEN_MAX_ALIGN_BYTES==0, AlignedMax==Unaligned, and many compilers generate warnings for friend-ing a class twice.
|
||||||
|
friend class Eigen::Map<Derived, AlignedMax>;
|
||||||
|
friend class Eigen::Map<const Derived, AlignedMax>;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -921,13 +999,19 @@ namespace internal {
|
||||||
template <typename Derived, typename OtherDerived, bool IsVector>
|
template <typename Derived, typename OtherDerived, bool IsVector>
|
||||||
struct conservative_resize_like_impl
|
struct conservative_resize_like_impl
|
||||||
{
|
{
|
||||||
|
#if EIGEN_HAS_TYPE_TRAITS
|
||||||
|
static const bool IsRelocatable = std::is_trivially_copyable<typename Derived::Scalar>::value;
|
||||||
|
#else
|
||||||
|
static const bool IsRelocatable = !NumTraits<typename Derived::Scalar>::RequireInitialization;
|
||||||
|
#endif
|
||||||
static void run(DenseBase<Derived>& _this, Index rows, Index cols)
|
static void run(DenseBase<Derived>& _this, Index rows, Index cols)
|
||||||
{
|
{
|
||||||
if (_this.rows() == rows && _this.cols() == cols) return;
|
if (_this.rows() == rows && _this.cols() == cols) return;
|
||||||
EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
|
EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
|
||||||
|
|
||||||
if ( ( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows
|
if ( IsRelocatable
|
||||||
(!Derived::IsRowMajor && _this.rows() == rows) ) // column-major and we change only the number of columns
|
&& (( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows
|
||||||
|
(!Derived::IsRowMajor && _this.rows() == rows) )) // column-major and we change only the number of columns
|
||||||
{
|
{
|
||||||
internal::check_rows_cols_for_overflow<Derived::MaxSizeAtCompileTime>::run(rows, cols);
|
internal::check_rows_cols_for_overflow<Derived::MaxSizeAtCompileTime>::run(rows, cols);
|
||||||
_this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
|
_this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
|
||||||
|
|
@ -935,7 +1019,7 @@ struct conservative_resize_like_impl
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// The storage order does not allow us to use reallocation.
|
// The storage order does not allow us to use reallocation.
|
||||||
typename Derived::PlainObject tmp(rows,cols);
|
Derived tmp(rows,cols);
|
||||||
const Index common_rows = numext::mini(rows, _this.rows());
|
const Index common_rows = numext::mini(rows, _this.rows());
|
||||||
const Index common_cols = numext::mini(cols, _this.cols());
|
const Index common_cols = numext::mini(cols, _this.cols());
|
||||||
tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
|
tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
|
||||||
|
|
@ -955,8 +1039,9 @@ struct conservative_resize_like_impl
|
||||||
EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
|
EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
|
||||||
EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
|
EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
|
||||||
|
|
||||||
if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) || // row-major and we change only the number of rows
|
if ( IsRelocatable &&
|
||||||
(!Derived::IsRowMajor && _this.rows() == other.rows()) ) // column-major and we change only the number of columns
|
(( Derived::IsRowMajor && _this.cols() == other.cols()) || // row-major and we change only the number of rows
|
||||||
|
(!Derived::IsRowMajor && _this.rows() == other.rows()) )) // column-major and we change only the number of columns
|
||||||
{
|
{
|
||||||
const Index new_rows = other.rows() - _this.rows();
|
const Index new_rows = other.rows() - _this.rows();
|
||||||
const Index new_cols = other.cols() - _this.cols();
|
const Index new_cols = other.cols() - _this.cols();
|
||||||
|
|
@ -969,7 +1054,7 @@ struct conservative_resize_like_impl
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// The storage order does not allow us to use reallocation.
|
// The storage order does not allow us to use reallocation.
|
||||||
typename Derived::PlainObject tmp(other);
|
Derived tmp(other);
|
||||||
const Index common_rows = numext::mini(tmp.rows(), _this.rows());
|
const Index common_rows = numext::mini(tmp.rows(), _this.rows());
|
||||||
const Index common_cols = numext::mini(tmp.cols(), _this.cols());
|
const Index common_cols = numext::mini(tmp.cols(), _this.cols());
|
||||||
tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
|
tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
|
||||||
|
|
@ -984,13 +1069,18 @@ template <typename Derived, typename OtherDerived>
|
||||||
struct conservative_resize_like_impl<Derived,OtherDerived,true>
|
struct conservative_resize_like_impl<Derived,OtherDerived,true>
|
||||||
: conservative_resize_like_impl<Derived,OtherDerived,false>
|
: conservative_resize_like_impl<Derived,OtherDerived,false>
|
||||||
{
|
{
|
||||||
using conservative_resize_like_impl<Derived,OtherDerived,false>::run;
|
typedef conservative_resize_like_impl<Derived,OtherDerived,false> Base;
|
||||||
|
using Base::run;
|
||||||
|
using Base::IsRelocatable;
|
||||||
|
|
||||||
static void run(DenseBase<Derived>& _this, Index size)
|
static void run(DenseBase<Derived>& _this, Index size)
|
||||||
{
|
{
|
||||||
const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size;
|
const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size;
|
||||||
const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1;
|
const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1;
|
||||||
|
if(IsRelocatable)
|
||||||
_this.derived().m_storage.conservativeResize(size,new_rows,new_cols);
|
_this.derived().m_storage.conservativeResize(size,new_rows,new_cols);
|
||||||
|
else
|
||||||
|
Base::run(_this.derived(), new_rows, new_cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
|
static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
|
||||||
|
|
@ -1001,7 +1091,10 @@ struct conservative_resize_like_impl<Derived,OtherDerived,true>
|
||||||
|
|
||||||
const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows();
|
const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows();
|
||||||
const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1;
|
const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1;
|
||||||
|
if(IsRelocatable)
|
||||||
_this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols);
|
_this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols);
|
||||||
|
else
|
||||||
|
Base::run(_this.derived(), new_rows, new_cols);
|
||||||
|
|
||||||
if (num_new_elements > 0)
|
if (num_new_elements > 0)
|
||||||
_this.tail(num_new_elements) = other.tail(num_new_elements);
|
_this.tail(num_new_elements) = other.tail(num_new_elements);
|
||||||
|
|
@ -1012,7 +1105,7 @@ template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
|
||||||
struct matrix_swap_impl
|
struct matrix_swap_impl
|
||||||
{
|
{
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
static inline void run(MatrixTypeA& a, MatrixTypeB& b)
|
static EIGEN_STRONG_INLINE void run(MatrixTypeA& a, MatrixTypeB& b)
|
||||||
{
|
{
|
||||||
a.base().swap(b);
|
a.base().swap(b);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,18 +90,23 @@ class Product : public ProductImpl<_Lhs,_Rhs,Option,
|
||||||
typedef typename internal::remove_all<LhsNested>::type LhsNestedCleaned;
|
typedef typename internal::remove_all<LhsNested>::type LhsNestedCleaned;
|
||||||
typedef typename internal::remove_all<RhsNested>::type RhsNestedCleaned;
|
typedef typename internal::remove_all<RhsNested>::type RhsNestedCleaned;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC Product(const Lhs& lhs, const Rhs& rhs) : m_lhs(lhs), m_rhs(rhs)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
Product(const Lhs& lhs, const Rhs& rhs) : m_lhs(lhs), m_rhs(rhs)
|
||||||
{
|
{
|
||||||
eigen_assert(lhs.cols() == rhs.rows()
|
eigen_assert(lhs.cols() == rhs.rows()
|
||||||
&& "invalid matrix product"
|
&& "invalid matrix product"
|
||||||
&& "if you wanted a coeff-wise or a dot product use the respective explicit functions");
|
&& "if you wanted a coeff-wise or a dot product use the respective explicit functions");
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rows() const { return m_lhs.rows(); }
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index cols() const { return m_rhs.cols(); }
|
Index rows() const EIGEN_NOEXCEPT { return m_lhs.rows(); }
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
|
Index cols() const EIGEN_NOEXCEPT { return m_rhs.cols(); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC const LhsNestedCleaned& lhs() const { return m_lhs; }
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
EIGEN_DEVICE_FUNC const RhsNestedCleaned& rhs() const { return m_rhs; }
|
const LhsNestedCleaned& lhs() const { return m_lhs; }
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
const RhsNestedCleaned& rhs() const { return m_rhs; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
@ -116,7 +121,7 @@ class dense_product_base
|
||||||
: public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
|
: public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
|
||||||
{};
|
{};
|
||||||
|
|
||||||
/** Convertion to scalar for inner-products */
|
/** Conversion to scalar for inner-products */
|
||||||
template<typename Lhs, typename Rhs, int Option>
|
template<typename Lhs, typename Rhs, int Option>
|
||||||
class dense_product_base<Lhs, Rhs, Option, InnerProduct>
|
class dense_product_base<Lhs, Rhs, Option, InnerProduct>
|
||||||
: public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
|
: public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
|
||||||
|
|
@ -127,7 +132,7 @@ public:
|
||||||
using Base::derived;
|
using Base::derived;
|
||||||
typedef typename Base::Scalar Scalar;
|
typedef typename Base::Scalar Scalar;
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE operator const Scalar() const
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE operator const Scalar() const
|
||||||
{
|
{
|
||||||
return internal::evaluator<ProductXpr>(derived()).coeff(0,0);
|
return internal::evaluator<ProductXpr>(derived()).coeff(0,0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ namespace internal {
|
||||||
/** \internal
|
/** \internal
|
||||||
* Evaluator of a product expression.
|
* Evaluator of a product expression.
|
||||||
* Since products require special treatments to handle all possible cases,
|
* Since products require special treatments to handle all possible cases,
|
||||||
* we simply deffer the evaluation logic to a product_evaluator class
|
* we simply defer the evaluation logic to a product_evaluator class
|
||||||
* which offers more partial specialization possibilities.
|
* which offers more partial specialization possibilities.
|
||||||
*
|
*
|
||||||
* \sa class product_evaluator
|
* \sa class product_evaluator
|
||||||
|
|
@ -128,7 +128,7 @@ protected:
|
||||||
PlainObject m_result;
|
PlainObject m_result;
|
||||||
};
|
};
|
||||||
|
|
||||||
// The following three shortcuts are enabled only if the scalar types match excatly.
|
// The following three shortcuts are enabled only if the scalar types match exactly.
|
||||||
// TODO: we could enable them for different scalar types when the product is not vectorized.
|
// TODO: we could enable them for different scalar types when the product is not vectorized.
|
||||||
|
|
||||||
// Dense = Product
|
// Dense = Product
|
||||||
|
|
@ -137,7 +137,7 @@ struct Assignment<DstXprType, Product<Lhs,Rhs,Options>, internal::assign_op<Scal
|
||||||
typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct)>::type>
|
typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct)>::type>
|
||||||
{
|
{
|
||||||
typedef Product<Lhs,Rhs,Options> SrcXprType;
|
typedef Product<Lhs,Rhs,Options> SrcXprType;
|
||||||
static EIGEN_STRONG_INLINE
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,Scalar> &)
|
void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,Scalar> &)
|
||||||
{
|
{
|
||||||
Index dstRows = src.rows();
|
Index dstRows = src.rows();
|
||||||
|
|
@ -155,7 +155,7 @@ struct Assignment<DstXprType, Product<Lhs,Rhs,Options>, internal::add_assign_op<
|
||||||
typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct)>::type>
|
typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct)>::type>
|
||||||
{
|
{
|
||||||
typedef Product<Lhs,Rhs,Options> SrcXprType;
|
typedef Product<Lhs,Rhs,Options> SrcXprType;
|
||||||
static EIGEN_STRONG_INLINE
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<Scalar,Scalar> &)
|
void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<Scalar,Scalar> &)
|
||||||
{
|
{
|
||||||
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
|
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
|
||||||
|
|
@ -170,7 +170,7 @@ struct Assignment<DstXprType, Product<Lhs,Rhs,Options>, internal::sub_assign_op<
|
||||||
typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct)>::type>
|
typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct)>::type>
|
||||||
{
|
{
|
||||||
typedef Product<Lhs,Rhs,Options> SrcXprType;
|
typedef Product<Lhs,Rhs,Options> SrcXprType;
|
||||||
static EIGEN_STRONG_INLINE
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<Scalar,Scalar> &)
|
void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<Scalar,Scalar> &)
|
||||||
{
|
{
|
||||||
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
|
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
|
||||||
|
|
@ -190,7 +190,7 @@ struct Assignment<DstXprType, CwiseBinaryOp<internal::scalar_product_op<ScalarBi
|
||||||
typedef CwiseBinaryOp<internal::scalar_product_op<ScalarBis,Scalar>,
|
typedef CwiseBinaryOp<internal::scalar_product_op<ScalarBis,Scalar>,
|
||||||
const CwiseNullaryOp<internal::scalar_constant_op<ScalarBis>,Plain>,
|
const CwiseNullaryOp<internal::scalar_constant_op<ScalarBis>,Plain>,
|
||||||
const Product<Lhs,Rhs,DefaultProduct> > SrcXprType;
|
const Product<Lhs,Rhs,DefaultProduct> > SrcXprType;
|
||||||
static EIGEN_STRONG_INLINE
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
void run(DstXprType &dst, const SrcXprType &src, const AssignFunc& func)
|
void run(DstXprType &dst, const SrcXprType &src, const AssignFunc& func)
|
||||||
{
|
{
|
||||||
call_assignment_no_alias(dst, (src.lhs().functor().m_other * src.rhs().lhs())*src.rhs().rhs(), func);
|
call_assignment_no_alias(dst, (src.lhs().functor().m_other * src.rhs().lhs())*src.rhs().rhs(), func);
|
||||||
|
|
@ -217,7 +217,7 @@ template<typename DstXprType, typename OtherXpr, typename ProductType, typename
|
||||||
struct assignment_from_xpr_op_product
|
struct assignment_from_xpr_op_product
|
||||||
{
|
{
|
||||||
template<typename SrcXprType, typename InitialFunc>
|
template<typename SrcXprType, typename InitialFunc>
|
||||||
static EIGEN_STRONG_INLINE
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
void run(DstXprType &dst, const SrcXprType &src, const InitialFunc& /*func*/)
|
void run(DstXprType &dst, const SrcXprType &src, const InitialFunc& /*func*/)
|
||||||
{
|
{
|
||||||
call_assignment_no_alias(dst, src.lhs(), Func1());
|
call_assignment_no_alias(dst, src.lhs(), Func1());
|
||||||
|
|
@ -246,19 +246,19 @@ template<typename Lhs, typename Rhs>
|
||||||
struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,InnerProduct>
|
struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,InnerProduct>
|
||||||
{
|
{
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
dst.coeffRef(0,0) = (lhs.transpose().cwiseProduct(rhs)).sum();
|
dst.coeffRef(0,0) = (lhs.transpose().cwiseProduct(rhs)).sum();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
dst.coeffRef(0,0) += (lhs.transpose().cwiseProduct(rhs)).sum();
|
dst.coeffRef(0,0) += (lhs.transpose().cwiseProduct(rhs)).sum();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{ dst.coeffRef(0,0) -= (lhs.transpose().cwiseProduct(rhs)).sum(); }
|
{ dst.coeffRef(0,0) -= (lhs.transpose().cwiseProduct(rhs)).sum(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -269,10 +269,10 @@ struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,InnerProduct>
|
||||||
|
|
||||||
// Column major result
|
// Column major result
|
||||||
template<typename Dst, typename Lhs, typename Rhs, typename Func>
|
template<typename Dst, typename Lhs, typename Rhs, typename Func>
|
||||||
void outer_product_selector_run(Dst& dst, const Lhs &lhs, const Rhs &rhs, const Func& func, const false_type&)
|
void EIGEN_DEVICE_FUNC outer_product_selector_run(Dst& dst, const Lhs &lhs, const Rhs &rhs, const Func& func, const false_type&)
|
||||||
{
|
{
|
||||||
evaluator<Rhs> rhsEval(rhs);
|
evaluator<Rhs> rhsEval(rhs);
|
||||||
typename nested_eval<Lhs,Rhs::SizeAtCompileTime>::type actual_lhs(lhs);
|
ei_declare_local_nested_eval(Lhs,lhs,Rhs::SizeAtCompileTime,actual_lhs);
|
||||||
// FIXME if cols is large enough, then it might be useful to make sure that lhs is sequentially stored
|
// FIXME if cols is large enough, then it might be useful to make sure that lhs is sequentially stored
|
||||||
// FIXME not very good if rhs is real and lhs complex while alpha is real too
|
// FIXME not very good if rhs is real and lhs complex while alpha is real too
|
||||||
const Index cols = dst.cols();
|
const Index cols = dst.cols();
|
||||||
|
|
@ -282,10 +282,10 @@ void outer_product_selector_run(Dst& dst, const Lhs &lhs, const Rhs &rhs, const
|
||||||
|
|
||||||
// Row major result
|
// Row major result
|
||||||
template<typename Dst, typename Lhs, typename Rhs, typename Func>
|
template<typename Dst, typename Lhs, typename Rhs, typename Func>
|
||||||
void outer_product_selector_run(Dst& dst, const Lhs &lhs, const Rhs &rhs, const Func& func, const true_type&)
|
void EIGEN_DEVICE_FUNC outer_product_selector_run(Dst& dst, const Lhs &lhs, const Rhs &rhs, const Func& func, const true_type&)
|
||||||
{
|
{
|
||||||
evaluator<Lhs> lhsEval(lhs);
|
evaluator<Lhs> lhsEval(lhs);
|
||||||
typename nested_eval<Rhs,Lhs::SizeAtCompileTime>::type actual_rhs(rhs);
|
ei_declare_local_nested_eval(Rhs,rhs,Lhs::SizeAtCompileTime,actual_rhs);
|
||||||
// FIXME if rows is large enough, then it might be useful to make sure that rhs is sequentially stored
|
// FIXME if rows is large enough, then it might be useful to make sure that rhs is sequentially stored
|
||||||
// FIXME not very good if lhs is real and rhs complex while alpha is real too
|
// FIXME not very good if lhs is real and rhs complex while alpha is real too
|
||||||
const Index rows = dst.rows();
|
const Index rows = dst.rows();
|
||||||
|
|
@ -300,37 +300,37 @@ struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,OuterProduct>
|
||||||
typedef typename Product<Lhs,Rhs>::Scalar Scalar;
|
typedef typename Product<Lhs,Rhs>::Scalar Scalar;
|
||||||
|
|
||||||
// TODO it would be nice to be able to exploit our *_assign_op functors for that purpose
|
// TODO it would be nice to be able to exploit our *_assign_op functors for that purpose
|
||||||
struct set { template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() = src; } };
|
struct set { template<typename Dst, typename Src> EIGEN_DEVICE_FUNC void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() = src; } };
|
||||||
struct add { template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() += src; } };
|
struct add { template<typename Dst, typename Src> EIGEN_DEVICE_FUNC void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() += src; } };
|
||||||
struct sub { template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() -= src; } };
|
struct sub { template<typename Dst, typename Src> EIGEN_DEVICE_FUNC void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() -= src; } };
|
||||||
struct adds {
|
struct adds {
|
||||||
Scalar m_scale;
|
Scalar m_scale;
|
||||||
explicit adds(const Scalar& s) : m_scale(s) {}
|
explicit adds(const Scalar& s) : m_scale(s) {}
|
||||||
template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const {
|
template<typename Dst, typename Src> void EIGEN_DEVICE_FUNC operator()(const Dst& dst, const Src& src) const {
|
||||||
dst.const_cast_derived() += m_scale * src;
|
dst.const_cast_derived() += m_scale * src;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
internal::outer_product_selector_run(dst, lhs, rhs, set(), is_row_major<Dst>());
|
internal::outer_product_selector_run(dst, lhs, rhs, set(), is_row_major<Dst>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
internal::outer_product_selector_run(dst, lhs, rhs, add(), is_row_major<Dst>());
|
internal::outer_product_selector_run(dst, lhs, rhs, add(), is_row_major<Dst>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
internal::outer_product_selector_run(dst, lhs, rhs, sub(), is_row_major<Dst>());
|
internal::outer_product_selector_run(dst, lhs, rhs, sub(), is_row_major<Dst>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_STRONG_INLINE void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
||||||
{
|
{
|
||||||
internal::outer_product_selector_run(dst, lhs, rhs, adds(alpha), is_row_major<Dst>());
|
internal::outer_product_selector_run(dst, lhs, rhs, adds(alpha), is_row_major<Dst>());
|
||||||
}
|
}
|
||||||
|
|
@ -345,19 +345,19 @@ struct generic_product_impl_base
|
||||||
typedef typename Product<Lhs,Rhs>::Scalar Scalar;
|
typedef typename Product<Lhs,Rhs>::Scalar Scalar;
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{ dst.setZero(); scaleAndAddTo(dst, lhs, rhs, Scalar(1)); }
|
{ dst.setZero(); scaleAndAddTo(dst, lhs, rhs, Scalar(1)); }
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{ scaleAndAddTo(dst,lhs, rhs, Scalar(1)); }
|
{ scaleAndAddTo(dst,lhs, rhs, Scalar(1)); }
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{ scaleAndAddTo(dst, lhs, rhs, Scalar(-1)); }
|
{ scaleAndAddTo(dst, lhs, rhs, Scalar(-1)); }
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_STRONG_INLINE void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
||||||
{ Derived::scaleAndAddTo(dst,lhs,rhs,alpha); }
|
{ Derived::scaleAndAddTo(dst,lhs,rhs,alpha); }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
@ -373,8 +373,13 @@ struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,GemvProduct>
|
||||||
typedef typename internal::remove_all<typename internal::conditional<int(Side)==OnTheRight,LhsNested,RhsNested>::type>::type MatrixType;
|
typedef typename internal::remove_all<typename internal::conditional<int(Side)==OnTheRight,LhsNested,RhsNested>::type>::type MatrixType;
|
||||||
|
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
static EIGEN_STRONG_INLINE void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
||||||
{
|
{
|
||||||
|
// Fallback to inner product if both the lhs and rhs is a runtime vector.
|
||||||
|
if (lhs.rows() == 1 && rhs.cols() == 1) {
|
||||||
|
dst.coeffRef(0,0) += alpha * lhs.row(0).conjugate().dot(rhs.col(0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
LhsNested actual_lhs(lhs);
|
LhsNested actual_lhs(lhs);
|
||||||
RhsNested actual_rhs(rhs);
|
RhsNested actual_rhs(rhs);
|
||||||
internal::gemv_dense_selector<Side,
|
internal::gemv_dense_selector<Side,
|
||||||
|
|
@ -390,7 +395,7 @@ struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,CoeffBasedProductMode>
|
||||||
typedef typename Product<Lhs,Rhs>::Scalar Scalar;
|
typedef typename Product<Lhs,Rhs>::Scalar Scalar;
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
// Same as: dst.noalias() = lhs.lazyProduct(rhs);
|
// Same as: dst.noalias() = lhs.lazyProduct(rhs);
|
||||||
// but easier on the compiler side
|
// but easier on the compiler side
|
||||||
|
|
@ -398,22 +403,71 @@ struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,CoeffBasedProductMode>
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
// dst.noalias() += lhs.lazyProduct(rhs);
|
// dst.noalias() += lhs.lazyProduct(rhs);
|
||||||
call_assignment_no_alias(dst, lhs.lazyProduct(rhs), internal::add_assign_op<typename Dst::Scalar,Scalar>());
|
call_assignment_no_alias(dst, lhs.lazyProduct(rhs), internal::add_assign_op<typename Dst::Scalar,Scalar>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Dst>
|
template<typename Dst>
|
||||||
static EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
// dst.noalias() -= lhs.lazyProduct(rhs);
|
// dst.noalias() -= lhs.lazyProduct(rhs);
|
||||||
call_assignment_no_alias(dst, lhs.lazyProduct(rhs), internal::sub_assign_op<typename Dst::Scalar,Scalar>());
|
call_assignment_no_alias(dst, lhs.lazyProduct(rhs), internal::sub_assign_op<typename Dst::Scalar,Scalar>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// template<typename Dst>
|
// This is a special evaluation path called from generic_product_impl<...,GemmProduct> in file GeneralMatrixMatrix.h
|
||||||
// static inline void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
// This variant tries to extract scalar multiples from both the LHS and RHS and factor them out. For instance:
|
||||||
// { dst.noalias() += alpha * lhs.lazyProduct(rhs); }
|
// dst {,+,-}= (s1*A)*(B*s2)
|
||||||
|
// will be rewritten as:
|
||||||
|
// dst {,+,-}= (s1*s2) * (A.lazyProduct(B))
|
||||||
|
// There are at least four benefits of doing so:
|
||||||
|
// 1 - huge performance gain for heap-allocated matrix types as it save costly allocations.
|
||||||
|
// 2 - it is faster than simply by-passing the heap allocation through stack allocation.
|
||||||
|
// 3 - it makes this fallback consistent with the heavy GEMM routine.
|
||||||
|
// 4 - it fully by-passes huge stack allocation attempts when multiplying huge fixed-size matrices.
|
||||||
|
// (see https://stackoverflow.com/questions/54738495)
|
||||||
|
// For small fixed sizes matrices, howver, the gains are less obvious, it is sometimes x2 faster, but sometimes x3 slower,
|
||||||
|
// and the behavior depends also a lot on the compiler... This is why this re-writting strategy is currently
|
||||||
|
// enabled only when falling back from the main GEMM.
|
||||||
|
template<typename Dst, typename Func>
|
||||||
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
void eval_dynamic(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Func &func)
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
HasScalarFactor = blas_traits<Lhs>::HasScalarFactor || blas_traits<Rhs>::HasScalarFactor,
|
||||||
|
ConjLhs = blas_traits<Lhs>::NeedToConjugate,
|
||||||
|
ConjRhs = blas_traits<Rhs>::NeedToConjugate
|
||||||
|
};
|
||||||
|
// FIXME: in c++11 this should be auto, and extractScalarFactor should also return auto
|
||||||
|
// this is important for real*complex_mat
|
||||||
|
Scalar actualAlpha = combine_scalar_factors<Scalar>(lhs, rhs);
|
||||||
|
|
||||||
|
eval_dynamic_impl(dst,
|
||||||
|
blas_traits<Lhs>::extract(lhs).template conjugateIf<ConjLhs>(),
|
||||||
|
blas_traits<Rhs>::extract(rhs).template conjugateIf<ConjRhs>(),
|
||||||
|
func,
|
||||||
|
actualAlpha,
|
||||||
|
typename conditional<HasScalarFactor,true_type,false_type>::type());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
template<typename Dst, typename LhsT, typename RhsT, typename Func, typename Scalar>
|
||||||
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
void eval_dynamic_impl(Dst& dst, const LhsT& lhs, const RhsT& rhs, const Func &func, const Scalar& s /* == 1 */, false_type)
|
||||||
|
{
|
||||||
|
EIGEN_UNUSED_VARIABLE(s);
|
||||||
|
eigen_internal_assert(s==Scalar(1));
|
||||||
|
call_restricted_packet_assignment_no_alias(dst, lhs.lazyProduct(rhs), func);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Dst, typename LhsT, typename RhsT, typename Func, typename Scalar>
|
||||||
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
void eval_dynamic_impl(Dst& dst, const LhsT& lhs, const RhsT& rhs, const Func &func, const Scalar& s, true_type)
|
||||||
|
{
|
||||||
|
call_restricted_packet_assignment_no_alias(dst, s * lhs.lazyProduct(rhs), func);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// This specialization enforces the use of a coefficient-based evaluation strategy
|
// This specialization enforces the use of a coefficient-based evaluation strategy
|
||||||
|
|
@ -495,7 +549,7 @@ struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape,
|
||||||
RhsCoeffReadCost = RhsEtorType::CoeffReadCost,
|
RhsCoeffReadCost = RhsEtorType::CoeffReadCost,
|
||||||
CoeffReadCost = InnerSize==0 ? NumTraits<Scalar>::ReadCost
|
CoeffReadCost = InnerSize==0 ? NumTraits<Scalar>::ReadCost
|
||||||
: InnerSize == Dynamic ? HugeCost
|
: InnerSize == Dynamic ? HugeCost
|
||||||
: InnerSize * (NumTraits<Scalar>::MulCost + LhsCoeffReadCost + RhsCoeffReadCost)
|
: InnerSize * (NumTraits<Scalar>::MulCost + int(LhsCoeffReadCost) + int(RhsCoeffReadCost))
|
||||||
+ (InnerSize - 1) * NumTraits<Scalar>::AddCost,
|
+ (InnerSize - 1) * NumTraits<Scalar>::AddCost,
|
||||||
|
|
||||||
Unroll = CoeffReadCost <= EIGEN_UNROLLING_LIMIT,
|
Unroll = CoeffReadCost <= EIGEN_UNROLLING_LIMIT,
|
||||||
|
|
@ -522,7 +576,7 @@ struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape,
|
||||||
: (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
|
: (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
|
||||||
: (bool(RhsRowMajor) && !CanVectorizeLhs),
|
: (bool(RhsRowMajor) && !CanVectorizeLhs),
|
||||||
|
|
||||||
Flags = ((unsigned int)(LhsFlags | RhsFlags) & HereditaryBits & ~RowMajorBit)
|
Flags = ((int(LhsFlags) | int(RhsFlags)) & HereditaryBits & ~RowMajorBit)
|
||||||
| (EvalToRowMajor ? RowMajorBit : 0)
|
| (EvalToRowMajor ? RowMajorBit : 0)
|
||||||
// TODO enable vectorization for mixed types
|
// TODO enable vectorization for mixed types
|
||||||
| (SameType && (CanVectorizeLhs || CanVectorizeRhs) ? PacketAccessBit : 0)
|
| (SameType && (CanVectorizeLhs || CanVectorizeRhs) ? PacketAccessBit : 0)
|
||||||
|
|
@ -543,8 +597,8 @@ struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape,
|
||||||
CanVectorizeInner = SameType
|
CanVectorizeInner = SameType
|
||||||
&& LhsRowMajor
|
&& LhsRowMajor
|
||||||
&& (!RhsRowMajor)
|
&& (!RhsRowMajor)
|
||||||
&& (LhsFlags & RhsFlags & ActualPacketAccessBit)
|
&& (int(LhsFlags) & int(RhsFlags) & ActualPacketAccessBit)
|
||||||
&& (InnerSize % packet_traits<Scalar>::size == 0)
|
&& (int(InnerSize) % packet_traits<Scalar>::size == 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index row, Index col) const
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index row, Index col) const
|
||||||
|
|
@ -556,7 +610,8 @@ struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape,
|
||||||
* which is why we don't set the LinearAccessBit.
|
* which is why we don't set the LinearAccessBit.
|
||||||
* TODO: this seems possible when the result is a vector
|
* TODO: this seems possible when the result is a vector
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC const CoeffReturnType coeff(Index index) const
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
const CoeffReturnType coeff(Index index) const
|
||||||
{
|
{
|
||||||
const Index row = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? 0 : index;
|
const Index row = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? 0 : index;
|
||||||
const Index col = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? index : 0;
|
const Index col = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? index : 0;
|
||||||
|
|
@ -564,6 +619,7 @@ struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape,
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
template<int LoadMode, typename PacketType>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
const PacketType packet(Index row, Index col) const
|
const PacketType packet(Index row, Index col) const
|
||||||
{
|
{
|
||||||
PacketType res;
|
PacketType res;
|
||||||
|
|
@ -575,6 +631,7 @@ struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape,
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
template<int LoadMode, typename PacketType>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
const PacketType packet(Index index) const
|
const PacketType packet(Index index) const
|
||||||
{
|
{
|
||||||
const Index row = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? 0 : index;
|
const Index row = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? 0 : index;
|
||||||
|
|
@ -603,7 +660,8 @@ struct product_evaluator<Product<Lhs, Rhs, DefaultProduct>, LazyCoeffBasedProduc
|
||||||
enum {
|
enum {
|
||||||
Flags = Base::Flags | EvalBeforeNestingBit
|
Flags = Base::Flags | EvalBeforeNestingBit
|
||||||
};
|
};
|
||||||
EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
explicit product_evaluator(const XprType& xpr)
|
||||||
: Base(BaseProduct(xpr.lhs(),xpr.rhs()))
|
: Base(BaseProduct(xpr.lhs(),xpr.rhs()))
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
@ -615,7 +673,7 @@ struct product_evaluator<Product<Lhs, Rhs, DefaultProduct>, LazyCoeffBasedProduc
|
||||||
template<int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
template<int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||||
struct etor_product_packet_impl<RowMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode>
|
struct etor_product_packet_impl<RowMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode>
|
||||||
{
|
{
|
||||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet &res)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet &res)
|
||||||
{
|
{
|
||||||
etor_product_packet_impl<RowMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, innerDim, res);
|
etor_product_packet_impl<RowMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, innerDim, res);
|
||||||
res = pmadd(pset1<Packet>(lhs.coeff(row, Index(UnrollingIndex-1))), rhs.template packet<LoadMode,Packet>(Index(UnrollingIndex-1), col), res);
|
res = pmadd(pset1<Packet>(lhs.coeff(row, Index(UnrollingIndex-1))), rhs.template packet<LoadMode,Packet>(Index(UnrollingIndex-1), col), res);
|
||||||
|
|
@ -625,7 +683,7 @@ struct etor_product_packet_impl<RowMajor, UnrollingIndex, Lhs, Rhs, Packet, Load
|
||||||
template<int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
template<int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||||
struct etor_product_packet_impl<ColMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode>
|
struct etor_product_packet_impl<ColMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode>
|
||||||
{
|
{
|
||||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet &res)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet &res)
|
||||||
{
|
{
|
||||||
etor_product_packet_impl<ColMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, innerDim, res);
|
etor_product_packet_impl<ColMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, innerDim, res);
|
||||||
res = pmadd(lhs.template packet<LoadMode,Packet>(row, Index(UnrollingIndex-1)), pset1<Packet>(rhs.coeff(Index(UnrollingIndex-1), col)), res);
|
res = pmadd(lhs.template packet<LoadMode,Packet>(row, Index(UnrollingIndex-1)), pset1<Packet>(rhs.coeff(Index(UnrollingIndex-1), col)), res);
|
||||||
|
|
@ -635,7 +693,7 @@ struct etor_product_packet_impl<ColMajor, UnrollingIndex, Lhs, Rhs, Packet, Load
|
||||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||||
struct etor_product_packet_impl<RowMajor, 1, Lhs, Rhs, Packet, LoadMode>
|
struct etor_product_packet_impl<RowMajor, 1, Lhs, Rhs, Packet, LoadMode>
|
||||||
{
|
{
|
||||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index /*innerDim*/, Packet &res)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index /*innerDim*/, Packet &res)
|
||||||
{
|
{
|
||||||
res = pmul(pset1<Packet>(lhs.coeff(row, Index(0))),rhs.template packet<LoadMode,Packet>(Index(0), col));
|
res = pmul(pset1<Packet>(lhs.coeff(row, Index(0))),rhs.template packet<LoadMode,Packet>(Index(0), col));
|
||||||
}
|
}
|
||||||
|
|
@ -644,7 +702,7 @@ struct etor_product_packet_impl<RowMajor, 1, Lhs, Rhs, Packet, LoadMode>
|
||||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||||
struct etor_product_packet_impl<ColMajor, 1, Lhs, Rhs, Packet, LoadMode>
|
struct etor_product_packet_impl<ColMajor, 1, Lhs, Rhs, Packet, LoadMode>
|
||||||
{
|
{
|
||||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index /*innerDim*/, Packet &res)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index /*innerDim*/, Packet &res)
|
||||||
{
|
{
|
||||||
res = pmul(lhs.template packet<LoadMode,Packet>(row, Index(0)), pset1<Packet>(rhs.coeff(Index(0), col)));
|
res = pmul(lhs.template packet<LoadMode,Packet>(row, Index(0)), pset1<Packet>(rhs.coeff(Index(0), col)));
|
||||||
}
|
}
|
||||||
|
|
@ -653,7 +711,7 @@ struct etor_product_packet_impl<ColMajor, 1, Lhs, Rhs, Packet, LoadMode>
|
||||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||||
struct etor_product_packet_impl<RowMajor, 0, Lhs, Rhs, Packet, LoadMode>
|
struct etor_product_packet_impl<RowMajor, 0, Lhs, Rhs, Packet, LoadMode>
|
||||||
{
|
{
|
||||||
static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, Index /*innerDim*/, Packet &res)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, Index /*innerDim*/, Packet &res)
|
||||||
{
|
{
|
||||||
res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
|
res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
|
||||||
}
|
}
|
||||||
|
|
@ -662,7 +720,7 @@ struct etor_product_packet_impl<RowMajor, 0, Lhs, Rhs, Packet, LoadMode>
|
||||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||||
struct etor_product_packet_impl<ColMajor, 0, Lhs, Rhs, Packet, LoadMode>
|
struct etor_product_packet_impl<ColMajor, 0, Lhs, Rhs, Packet, LoadMode>
|
||||||
{
|
{
|
||||||
static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, Index /*innerDim*/, Packet &res)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, Index /*innerDim*/, Packet &res)
|
||||||
{
|
{
|
||||||
res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
|
res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
|
||||||
}
|
}
|
||||||
|
|
@ -671,7 +729,7 @@ struct etor_product_packet_impl<ColMajor, 0, Lhs, Rhs, Packet, LoadMode>
|
||||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||||
struct etor_product_packet_impl<RowMajor, Dynamic, Lhs, Rhs, Packet, LoadMode>
|
struct etor_product_packet_impl<RowMajor, Dynamic, Lhs, Rhs, Packet, LoadMode>
|
||||||
{
|
{
|
||||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet& res)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet& res)
|
||||||
{
|
{
|
||||||
res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
|
res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
|
||||||
for(Index i = 0; i < innerDim; ++i)
|
for(Index i = 0; i < innerDim; ++i)
|
||||||
|
|
@ -682,7 +740,7 @@ struct etor_product_packet_impl<RowMajor, Dynamic, Lhs, Rhs, Packet, LoadMode>
|
||||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||||
struct etor_product_packet_impl<ColMajor, Dynamic, Lhs, Rhs, Packet, LoadMode>
|
struct etor_product_packet_impl<ColMajor, Dynamic, Lhs, Rhs, Packet, LoadMode>
|
||||||
{
|
{
|
||||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet& res)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet& res)
|
||||||
{
|
{
|
||||||
res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
|
res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
|
||||||
for(Index i = 0; i < innerDim; ++i)
|
for(Index i = 0; i < innerDim; ++i)
|
||||||
|
|
@ -741,7 +799,8 @@ struct generic_product_impl<Lhs,Rhs,SelfAdjointShape,DenseShape,ProductTag>
|
||||||
typedef typename Product<Lhs,Rhs>::Scalar Scalar;
|
typedef typename Product<Lhs,Rhs>::Scalar Scalar;
|
||||||
|
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
static EIGEN_DEVICE_FUNC
|
||||||
|
void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
|
||||||
{
|
{
|
||||||
selfadjoint_product_impl<typename Lhs::MatrixType,Lhs::Mode,false,Rhs,0,Rhs::IsVectorAtCompileTime>::run(dst, lhs.nestedExpression(), rhs, alpha);
|
selfadjoint_product_impl<typename Lhs::MatrixType,Lhs::Mode,false,Rhs,0,Rhs::IsVectorAtCompileTime>::run(dst, lhs.nestedExpression(), rhs, alpha);
|
||||||
}
|
}
|
||||||
|
|
@ -772,17 +831,25 @@ struct diagonal_product_evaluator_base
|
||||||
typedef typename ScalarBinaryOpTraits<typename MatrixType::Scalar, typename DiagonalType::Scalar>::ReturnType Scalar;
|
typedef typename ScalarBinaryOpTraits<typename MatrixType::Scalar, typename DiagonalType::Scalar>::ReturnType Scalar;
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
CoeffReadCost = NumTraits<Scalar>::MulCost + evaluator<MatrixType>::CoeffReadCost + evaluator<DiagonalType>::CoeffReadCost,
|
CoeffReadCost = int(NumTraits<Scalar>::MulCost) + int(evaluator<MatrixType>::CoeffReadCost) + int(evaluator<DiagonalType>::CoeffReadCost),
|
||||||
|
|
||||||
MatrixFlags = evaluator<MatrixType>::Flags,
|
MatrixFlags = evaluator<MatrixType>::Flags,
|
||||||
DiagFlags = evaluator<DiagonalType>::Flags,
|
DiagFlags = evaluator<DiagonalType>::Flags,
|
||||||
_StorageOrder = MatrixFlags & RowMajorBit ? RowMajor : ColMajor,
|
|
||||||
|
_StorageOrder = (Derived::MaxRowsAtCompileTime==1 && Derived::MaxColsAtCompileTime!=1) ? RowMajor
|
||||||
|
: (Derived::MaxColsAtCompileTime==1 && Derived::MaxRowsAtCompileTime!=1) ? ColMajor
|
||||||
|
: MatrixFlags & RowMajorBit ? RowMajor : ColMajor,
|
||||||
|
_SameStorageOrder = _StorageOrder == (MatrixFlags & RowMajorBit ? RowMajor : ColMajor),
|
||||||
|
|
||||||
_ScalarAccessOnDiag = !((int(_StorageOrder) == ColMajor && int(ProductOrder) == OnTheLeft)
|
_ScalarAccessOnDiag = !((int(_StorageOrder) == ColMajor && int(ProductOrder) == OnTheLeft)
|
||||||
||(int(_StorageOrder) == RowMajor && int(ProductOrder) == OnTheRight)),
|
||(int(_StorageOrder) == RowMajor && int(ProductOrder) == OnTheRight)),
|
||||||
_SameTypes = is_same<typename MatrixType::Scalar, typename DiagonalType::Scalar>::value,
|
_SameTypes = is_same<typename MatrixType::Scalar, typename DiagonalType::Scalar>::value,
|
||||||
// FIXME currently we need same types, but in the future the next rule should be the one
|
// FIXME currently we need same types, but in the future the next rule should be the one
|
||||||
//_Vectorizable = bool(int(MatrixFlags)&PacketAccessBit) && ((!_PacketOnDiag) || (_SameTypes && bool(int(DiagFlags)&PacketAccessBit))),
|
//_Vectorizable = bool(int(MatrixFlags)&PacketAccessBit) && ((!_PacketOnDiag) || (_SameTypes && bool(int(DiagFlags)&PacketAccessBit))),
|
||||||
_Vectorizable = bool(int(MatrixFlags)&PacketAccessBit) && _SameTypes && (_ScalarAccessOnDiag || (bool(int(DiagFlags)&PacketAccessBit))),
|
_Vectorizable = bool(int(MatrixFlags)&PacketAccessBit)
|
||||||
|
&& _SameTypes
|
||||||
|
&& (_SameStorageOrder || (MatrixFlags&LinearAccessBit)==LinearAccessBit)
|
||||||
|
&& (_ScalarAccessOnDiag || (bool(int(DiagFlags)&PacketAccessBit))),
|
||||||
_LinearAccessMask = (MatrixType::RowsAtCompileTime==1 || MatrixType::ColsAtCompileTime==1) ? LinearAccessBit : 0,
|
_LinearAccessMask = (MatrixType::RowsAtCompileTime==1 || MatrixType::ColsAtCompileTime==1) ? LinearAccessBit : 0,
|
||||||
Flags = ((HereditaryBits|_LinearAccessMask) & (unsigned int)(MatrixFlags)) | (_Vectorizable ? PacketAccessBit : 0),
|
Flags = ((HereditaryBits|_LinearAccessMask) & (unsigned int)(MatrixFlags)) | (_Vectorizable ? PacketAccessBit : 0),
|
||||||
Alignment = evaluator<MatrixType>::Alignment,
|
Alignment = evaluator<MatrixType>::Alignment,
|
||||||
|
|
@ -792,7 +859,7 @@ public:
|
||||||
|| (DiagonalType::SizeAtCompileTime==Dynamic && MatrixType::ColsAtCompileTime==1 && ProductOrder==OnTheRight)
|
|| (DiagonalType::SizeAtCompileTime==Dynamic && MatrixType::ColsAtCompileTime==1 && ProductOrder==OnTheRight)
|
||||||
};
|
};
|
||||||
|
|
||||||
diagonal_product_evaluator_base(const MatrixType &mat, const DiagonalType &diag)
|
EIGEN_DEVICE_FUNC diagonal_product_evaluator_base(const MatrixType &mat, const DiagonalType &diag)
|
||||||
: m_diagImpl(diag), m_matImpl(mat)
|
: m_diagImpl(diag), m_matImpl(mat)
|
||||||
{
|
{
|
||||||
EIGEN_INTERNAL_CHECK_COST_VALUE(NumTraits<Scalar>::MulCost);
|
EIGEN_INTERNAL_CHECK_COST_VALUE(NumTraits<Scalar>::MulCost);
|
||||||
|
|
@ -843,10 +910,10 @@ struct product_evaluator<Product<Lhs, Rhs, ProductKind>, ProductTag, DiagonalSha
|
||||||
|
|
||||||
typedef Product<Lhs, Rhs, ProductKind> XprType;
|
typedef Product<Lhs, Rhs, ProductKind> XprType;
|
||||||
typedef typename XprType::PlainObject PlainObject;
|
typedef typename XprType::PlainObject PlainObject;
|
||||||
|
typedef typename Lhs::DiagonalVectorType DiagonalType;
|
||||||
|
|
||||||
enum {
|
|
||||||
StorageOrder = int(Rhs::Flags) & RowMajorBit ? RowMajor : ColMajor
|
enum { StorageOrder = Base::_StorageOrder };
|
||||||
};
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr)
|
EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr)
|
||||||
: Base(xpr.rhs(), xpr.lhs().diagonal())
|
: Base(xpr.rhs(), xpr.lhs().diagonal())
|
||||||
|
|
@ -858,7 +925,7 @@ struct product_evaluator<Product<Lhs, Rhs, ProductKind>, ProductTag, DiagonalSha
|
||||||
return m_diagImpl.coeff(row) * m_matImpl.coeff(row, col);
|
return m_diagImpl.coeff(row) * m_matImpl.coeff(row, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef __CUDACC__
|
#ifndef EIGEN_GPUCC
|
||||||
template<int LoadMode,typename PacketType>
|
template<int LoadMode,typename PacketType>
|
||||||
EIGEN_STRONG_INLINE PacketType packet(Index row, Index col) const
|
EIGEN_STRONG_INLINE PacketType packet(Index row, Index col) const
|
||||||
{
|
{
|
||||||
|
|
@ -890,7 +957,7 @@ struct product_evaluator<Product<Lhs, Rhs, ProductKind>, ProductTag, DenseShape,
|
||||||
typedef Product<Lhs, Rhs, ProductKind> XprType;
|
typedef Product<Lhs, Rhs, ProductKind> XprType;
|
||||||
typedef typename XprType::PlainObject PlainObject;
|
typedef typename XprType::PlainObject PlainObject;
|
||||||
|
|
||||||
enum { StorageOrder = int(Lhs::Flags) & RowMajorBit ? RowMajor : ColMajor };
|
enum { StorageOrder = Base::_StorageOrder };
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr)
|
EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr)
|
||||||
: Base(xpr.lhs(), xpr.rhs().diagonal())
|
: Base(xpr.lhs(), xpr.rhs().diagonal())
|
||||||
|
|
@ -902,7 +969,7 @@ struct product_evaluator<Product<Lhs, Rhs, ProductKind>, ProductTag, DenseShape,
|
||||||
return m_matImpl.coeff(row, col) * m_diagImpl.coeff(col);
|
return m_matImpl.coeff(row, col) * m_diagImpl.coeff(col);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef __CUDACC__
|
#ifndef EIGEN_GPUCC
|
||||||
template<int LoadMode,typename PacketType>
|
template<int LoadMode,typename PacketType>
|
||||||
EIGEN_STRONG_INLINE PacketType packet(Index row, Index col) const
|
EIGEN_STRONG_INLINE PacketType packet(Index row, Index col) const
|
||||||
{
|
{
|
||||||
|
|
@ -937,7 +1004,7 @@ struct permutation_matrix_product<ExpressionType, Side, Transposed, DenseShape>
|
||||||
typedef typename remove_all<MatrixType>::type MatrixTypeCleaned;
|
typedef typename remove_all<MatrixType>::type MatrixTypeCleaned;
|
||||||
|
|
||||||
template<typename Dest, typename PermutationType>
|
template<typename Dest, typename PermutationType>
|
||||||
static inline void run(Dest& dst, const PermutationType& perm, const ExpressionType& xpr)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Dest& dst, const PermutationType& perm, const ExpressionType& xpr)
|
||||||
{
|
{
|
||||||
MatrixType mat(xpr);
|
MatrixType mat(xpr);
|
||||||
const Index n = Side==OnTheLeft ? mat.rows() : mat.cols();
|
const Index n = Side==OnTheLeft ? mat.rows() : mat.cols();
|
||||||
|
|
@ -991,7 +1058,7 @@ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
|
||||||
struct generic_product_impl<Lhs, Rhs, PermutationShape, MatrixShape, ProductTag>
|
struct generic_product_impl<Lhs, Rhs, PermutationShape, MatrixShape, ProductTag>
|
||||||
{
|
{
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
permutation_matrix_product<Rhs, OnTheLeft, false, MatrixShape>::run(dst, lhs, rhs);
|
permutation_matrix_product<Rhs, OnTheLeft, false, MatrixShape>::run(dst, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
@ -1001,7 +1068,7 @@ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
|
||||||
struct generic_product_impl<Lhs, Rhs, MatrixShape, PermutationShape, ProductTag>
|
struct generic_product_impl<Lhs, Rhs, MatrixShape, PermutationShape, ProductTag>
|
||||||
{
|
{
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
permutation_matrix_product<Lhs, OnTheRight, false, MatrixShape>::run(dst, rhs, lhs);
|
permutation_matrix_product<Lhs, OnTheRight, false, MatrixShape>::run(dst, rhs, lhs);
|
||||||
}
|
}
|
||||||
|
|
@ -1011,7 +1078,7 @@ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
|
||||||
struct generic_product_impl<Inverse<Lhs>, Rhs, PermutationShape, MatrixShape, ProductTag>
|
struct generic_product_impl<Inverse<Lhs>, Rhs, PermutationShape, MatrixShape, ProductTag>
|
||||||
{
|
{
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
static void evalTo(Dest& dst, const Inverse<Lhs>& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Inverse<Lhs>& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
permutation_matrix_product<Rhs, OnTheLeft, true, MatrixShape>::run(dst, lhs.nestedExpression(), rhs);
|
permutation_matrix_product<Rhs, OnTheLeft, true, MatrixShape>::run(dst, lhs.nestedExpression(), rhs);
|
||||||
}
|
}
|
||||||
|
|
@ -1021,7 +1088,7 @@ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
|
||||||
struct generic_product_impl<Lhs, Inverse<Rhs>, MatrixShape, PermutationShape, ProductTag>
|
struct generic_product_impl<Lhs, Inverse<Rhs>, MatrixShape, PermutationShape, ProductTag>
|
||||||
{
|
{
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
static void evalTo(Dest& dst, const Lhs& lhs, const Inverse<Rhs>& rhs)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Inverse<Rhs>& rhs)
|
||||||
{
|
{
|
||||||
permutation_matrix_product<Lhs, OnTheRight, true, MatrixShape>::run(dst, rhs.nestedExpression(), lhs);
|
permutation_matrix_product<Lhs, OnTheRight, true, MatrixShape>::run(dst, rhs.nestedExpression(), lhs);
|
||||||
}
|
}
|
||||||
|
|
@ -1045,7 +1112,7 @@ struct transposition_matrix_product
|
||||||
typedef typename remove_all<MatrixType>::type MatrixTypeCleaned;
|
typedef typename remove_all<MatrixType>::type MatrixTypeCleaned;
|
||||||
|
|
||||||
template<typename Dest, typename TranspositionType>
|
template<typename Dest, typename TranspositionType>
|
||||||
static inline void run(Dest& dst, const TranspositionType& tr, const ExpressionType& xpr)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Dest& dst, const TranspositionType& tr, const ExpressionType& xpr)
|
||||||
{
|
{
|
||||||
MatrixType mat(xpr);
|
MatrixType mat(xpr);
|
||||||
typedef typename TranspositionType::StorageIndex StorageIndex;
|
typedef typename TranspositionType::StorageIndex StorageIndex;
|
||||||
|
|
@ -1068,7 +1135,7 @@ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
|
||||||
struct generic_product_impl<Lhs, Rhs, TranspositionsShape, MatrixShape, ProductTag>
|
struct generic_product_impl<Lhs, Rhs, TranspositionsShape, MatrixShape, ProductTag>
|
||||||
{
|
{
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
transposition_matrix_product<Rhs, OnTheLeft, false, MatrixShape>::run(dst, lhs, rhs);
|
transposition_matrix_product<Rhs, OnTheLeft, false, MatrixShape>::run(dst, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
@ -1078,7 +1145,7 @@ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
|
||||||
struct generic_product_impl<Lhs, Rhs, MatrixShape, TranspositionsShape, ProductTag>
|
struct generic_product_impl<Lhs, Rhs, MatrixShape, TranspositionsShape, ProductTag>
|
||||||
{
|
{
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
transposition_matrix_product<Lhs, OnTheRight, false, MatrixShape>::run(dst, rhs, lhs);
|
transposition_matrix_product<Lhs, OnTheRight, false, MatrixShape>::run(dst, rhs, lhs);
|
||||||
}
|
}
|
||||||
|
|
@ -1089,7 +1156,7 @@ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
|
||||||
struct generic_product_impl<Transpose<Lhs>, Rhs, TranspositionsShape, MatrixShape, ProductTag>
|
struct generic_product_impl<Transpose<Lhs>, Rhs, TranspositionsShape, MatrixShape, ProductTag>
|
||||||
{
|
{
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
static void evalTo(Dest& dst, const Transpose<Lhs>& lhs, const Rhs& rhs)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Transpose<Lhs>& lhs, const Rhs& rhs)
|
||||||
{
|
{
|
||||||
transposition_matrix_product<Rhs, OnTheLeft, true, MatrixShape>::run(dst, lhs.nestedExpression(), rhs);
|
transposition_matrix_product<Rhs, OnTheLeft, true, MatrixShape>::run(dst, lhs.nestedExpression(), rhs);
|
||||||
}
|
}
|
||||||
|
|
@ -1099,7 +1166,7 @@ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
|
||||||
struct generic_product_impl<Lhs, Transpose<Rhs>, MatrixShape, TranspositionsShape, ProductTag>
|
struct generic_product_impl<Lhs, Transpose<Rhs>, MatrixShape, TranspositionsShape, ProductTag>
|
||||||
{
|
{
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
static void evalTo(Dest& dst, const Lhs& lhs, const Transpose<Rhs>& rhs)
|
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Transpose<Rhs>& rhs)
|
||||||
{
|
{
|
||||||
transposition_matrix_product<Lhs, OnTheRight, true, MatrixShape>::run(dst, rhs.nestedExpression(), lhs);
|
transposition_matrix_product<Lhs, OnTheRight, true, MatrixShape>::run(dst, rhs.nestedExpression(), lhs);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,7 @@ DenseBase<Derived>::Random()
|
||||||
* \sa class CwiseNullaryOp, setRandom(Index), setRandom(Index,Index)
|
* \sa class CwiseNullaryOp, setRandom(Index), setRandom(Index,Index)
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline Derived& DenseBase<Derived>::setRandom()
|
EIGEN_DEVICE_FUNC inline Derived& DenseBase<Derived>::setRandom()
|
||||||
{
|
{
|
||||||
return *this = Random(rows(), cols());
|
return *this = Random(rows(), cols());
|
||||||
}
|
}
|
||||||
|
|
@ -177,6 +177,42 @@ PlainObjectBase<Derived>::setRandom(Index rows, Index cols)
|
||||||
return setRandom();
|
return setRandom();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Resizes to the given size, changing only the number of columns, and sets all
|
||||||
|
* coefficients in this expression to random values. For the parameter of type
|
||||||
|
* NoChange_t, just pass the special value \c NoChange.
|
||||||
|
*
|
||||||
|
* Numbers are uniformly spread through their whole definition range for integer types,
|
||||||
|
* and in the [-1:1] range for floating point scalar types.
|
||||||
|
*
|
||||||
|
* \not_reentrant
|
||||||
|
*
|
||||||
|
* \sa DenseBase::setRandom(), setRandom(Index), setRandom(Index, NoChange_t), class CwiseNullaryOp, DenseBase::Random()
|
||||||
|
*/
|
||||||
|
template<typename Derived>
|
||||||
|
EIGEN_STRONG_INLINE Derived&
|
||||||
|
PlainObjectBase<Derived>::setRandom(NoChange_t, Index cols)
|
||||||
|
{
|
||||||
|
return setRandom(rows(), cols);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Resizes to the given size, changing only the number of rows, and sets all
|
||||||
|
* coefficients in this expression to random values. For the parameter of type
|
||||||
|
* NoChange_t, just pass the special value \c NoChange.
|
||||||
|
*
|
||||||
|
* Numbers are uniformly spread through their whole definition range for integer types,
|
||||||
|
* and in the [-1:1] range for floating point scalar types.
|
||||||
|
*
|
||||||
|
* \not_reentrant
|
||||||
|
*
|
||||||
|
* \sa DenseBase::setRandom(), setRandom(Index), setRandom(NoChange_t, Index), class CwiseNullaryOp, DenseBase::Random()
|
||||||
|
*/
|
||||||
|
template<typename Derived>
|
||||||
|
EIGEN_STRONG_INLINE Derived&
|
||||||
|
PlainObjectBase<Derived>::setRandom(Index rows, NoChange_t)
|
||||||
|
{
|
||||||
|
return setRandom(rows, cols());
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_RANDOM_H
|
#endif // EIGEN_RANDOM_H
|
||||||
|
|
|
||||||
|
|
@ -23,23 +23,29 @@ namespace internal {
|
||||||
* Part 1 : the logic deciding a strategy for vectorization and unrolling
|
* Part 1 : the logic deciding a strategy for vectorization and unrolling
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
template<typename Func, typename Derived>
|
template<typename Func, typename Evaluator>
|
||||||
struct redux_traits
|
struct redux_traits
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename find_best_packet<typename Derived::Scalar,Derived::SizeAtCompileTime>::type PacketType;
|
typedef typename find_best_packet<typename Evaluator::Scalar,Evaluator::SizeAtCompileTime>::type PacketType;
|
||||||
enum {
|
enum {
|
||||||
PacketSize = unpacket_traits<PacketType>::size,
|
PacketSize = unpacket_traits<PacketType>::size,
|
||||||
InnerMaxSize = int(Derived::IsRowMajor)
|
InnerMaxSize = int(Evaluator::IsRowMajor)
|
||||||
? Derived::MaxColsAtCompileTime
|
? Evaluator::MaxColsAtCompileTime
|
||||||
: Derived::MaxRowsAtCompileTime
|
: Evaluator::MaxRowsAtCompileTime,
|
||||||
|
OuterMaxSize = int(Evaluator::IsRowMajor)
|
||||||
|
? Evaluator::MaxRowsAtCompileTime
|
||||||
|
: Evaluator::MaxColsAtCompileTime,
|
||||||
|
SliceVectorizedWork = int(InnerMaxSize)==Dynamic ? Dynamic
|
||||||
|
: int(OuterMaxSize)==Dynamic ? (int(InnerMaxSize)>=int(PacketSize) ? Dynamic : 0)
|
||||||
|
: (int(InnerMaxSize)/int(PacketSize)) * int(OuterMaxSize)
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MightVectorize = (int(Derived::Flags)&ActualPacketAccessBit)
|
MightVectorize = (int(Evaluator::Flags)&ActualPacketAccessBit)
|
||||||
&& (functor_traits<Func>::PacketAccess),
|
&& (functor_traits<Func>::PacketAccess),
|
||||||
MayLinearVectorize = bool(MightVectorize) && (int(Derived::Flags)&LinearAccessBit),
|
MayLinearVectorize = bool(MightVectorize) && (int(Evaluator::Flags)&LinearAccessBit),
|
||||||
MaySliceVectorize = bool(MightVectorize) && int(InnerMaxSize)>=3*PacketSize
|
MaySliceVectorize = bool(MightVectorize) && (int(SliceVectorizedWork)==Dynamic || int(SliceVectorizedWork)>=3)
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -51,8 +57,8 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
Cost = Derived::SizeAtCompileTime == Dynamic ? HugeCost
|
Cost = Evaluator::SizeAtCompileTime == Dynamic ? HugeCost
|
||||||
: Derived::SizeAtCompileTime * Derived::CoeffReadCost + (Derived::SizeAtCompileTime-1) * functor_traits<Func>::Cost,
|
: int(Evaluator::SizeAtCompileTime) * int(Evaluator::CoeffReadCost) + (Evaluator::SizeAtCompileTime-1) * functor_traits<Func>::Cost,
|
||||||
UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Traversal) == int(DefaultTraversal) ? 1 : int(PacketSize))
|
UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Traversal) == int(DefaultTraversal) ? 1 : int(PacketSize))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -64,18 +70,20 @@ public:
|
||||||
#ifdef EIGEN_DEBUG_ASSIGN
|
#ifdef EIGEN_DEBUG_ASSIGN
|
||||||
static void debug()
|
static void debug()
|
||||||
{
|
{
|
||||||
std::cerr << "Xpr: " << typeid(typename Derived::XprType).name() << std::endl;
|
std::cerr << "Xpr: " << typeid(typename Evaluator::XprType).name() << std::endl;
|
||||||
std::cerr.setf(std::ios::hex, std::ios::basefield);
|
std::cerr.setf(std::ios::hex, std::ios::basefield);
|
||||||
EIGEN_DEBUG_VAR(Derived::Flags)
|
EIGEN_DEBUG_VAR(Evaluator::Flags)
|
||||||
std::cerr.unsetf(std::ios::hex);
|
std::cerr.unsetf(std::ios::hex);
|
||||||
EIGEN_DEBUG_VAR(InnerMaxSize)
|
EIGEN_DEBUG_VAR(InnerMaxSize)
|
||||||
|
EIGEN_DEBUG_VAR(OuterMaxSize)
|
||||||
|
EIGEN_DEBUG_VAR(SliceVectorizedWork)
|
||||||
EIGEN_DEBUG_VAR(PacketSize)
|
EIGEN_DEBUG_VAR(PacketSize)
|
||||||
EIGEN_DEBUG_VAR(MightVectorize)
|
EIGEN_DEBUG_VAR(MightVectorize)
|
||||||
EIGEN_DEBUG_VAR(MayLinearVectorize)
|
EIGEN_DEBUG_VAR(MayLinearVectorize)
|
||||||
EIGEN_DEBUG_VAR(MaySliceVectorize)
|
EIGEN_DEBUG_VAR(MaySliceVectorize)
|
||||||
EIGEN_DEBUG_VAR(Traversal)
|
std::cerr << "Traversal" << " = " << Traversal << " (" << demangle_traversal(Traversal) << ")" << std::endl;
|
||||||
EIGEN_DEBUG_VAR(UnrollingLimit)
|
EIGEN_DEBUG_VAR(UnrollingLimit)
|
||||||
EIGEN_DEBUG_VAR(Unrolling)
|
std::cerr << "Unrolling" << " = " << Unrolling << " (" << demangle_unrolling(Unrolling) << ")" << std::endl;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -87,88 +95,86 @@ public:
|
||||||
|
|
||||||
/*** no vectorization ***/
|
/*** no vectorization ***/
|
||||||
|
|
||||||
template<typename Func, typename Derived, int Start, int Length>
|
template<typename Func, typename Evaluator, int Start, int Length>
|
||||||
struct redux_novec_unroller
|
struct redux_novec_unroller
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
HalfLength = Length/2
|
HalfLength = Length/2
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef typename Derived::Scalar Scalar;
|
typedef typename Evaluator::Scalar Scalar;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func& func)
|
static EIGEN_STRONG_INLINE Scalar run(const Evaluator &eval, const Func& func)
|
||||||
{
|
{
|
||||||
return func(redux_novec_unroller<Func, Derived, Start, HalfLength>::run(mat,func),
|
return func(redux_novec_unroller<Func, Evaluator, Start, HalfLength>::run(eval,func),
|
||||||
redux_novec_unroller<Func, Derived, Start+HalfLength, Length-HalfLength>::run(mat,func));
|
redux_novec_unroller<Func, Evaluator, Start+HalfLength, Length-HalfLength>::run(eval,func));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Func, typename Derived, int Start>
|
template<typename Func, typename Evaluator, int Start>
|
||||||
struct redux_novec_unroller<Func, Derived, Start, 1>
|
struct redux_novec_unroller<Func, Evaluator, Start, 1>
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
outer = Start / Derived::InnerSizeAtCompileTime,
|
outer = Start / Evaluator::InnerSizeAtCompileTime,
|
||||||
inner = Start % Derived::InnerSizeAtCompileTime
|
inner = Start % Evaluator::InnerSizeAtCompileTime
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef typename Derived::Scalar Scalar;
|
typedef typename Evaluator::Scalar Scalar;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func&)
|
static EIGEN_STRONG_INLINE Scalar run(const Evaluator &eval, const Func&)
|
||||||
{
|
{
|
||||||
return mat.coeffByOuterInner(outer, inner);
|
return eval.coeffByOuterInner(outer, inner);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is actually dead code and will never be called. It is required
|
// This is actually dead code and will never be called. It is required
|
||||||
// to prevent false warnings regarding failed inlining though
|
// to prevent false warnings regarding failed inlining though
|
||||||
// for 0 length run() will never be called at all.
|
// for 0 length run() will never be called at all.
|
||||||
template<typename Func, typename Derived, int Start>
|
template<typename Func, typename Evaluator, int Start>
|
||||||
struct redux_novec_unroller<Func, Derived, Start, 0>
|
struct redux_novec_unroller<Func, Evaluator, Start, 0>
|
||||||
{
|
{
|
||||||
typedef typename Derived::Scalar Scalar;
|
typedef typename Evaluator::Scalar Scalar;
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
static EIGEN_STRONG_INLINE Scalar run(const Derived&, const Func&) { return Scalar(); }
|
static EIGEN_STRONG_INLINE Scalar run(const Evaluator&, const Func&) { return Scalar(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/*** vectorization ***/
|
/*** vectorization ***/
|
||||||
|
|
||||||
template<typename Func, typename Derived, int Start, int Length>
|
template<typename Func, typename Evaluator, int Start, int Length>
|
||||||
struct redux_vec_unroller
|
struct redux_vec_unroller
|
||||||
|
{
|
||||||
|
template<typename PacketType>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
static EIGEN_STRONG_INLINE PacketType run(const Evaluator &eval, const Func& func)
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
PacketSize = redux_traits<Func, Derived>::PacketSize,
|
PacketSize = unpacket_traits<PacketType>::size,
|
||||||
HalfLength = Length/2
|
HalfLength = Length/2
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef typename Derived::Scalar Scalar;
|
|
||||||
typedef typename redux_traits<Func, Derived>::PacketType PacketScalar;
|
|
||||||
|
|
||||||
static EIGEN_STRONG_INLINE PacketScalar run(const Derived &mat, const Func& func)
|
|
||||||
{
|
|
||||||
return func.packetOp(
|
return func.packetOp(
|
||||||
redux_vec_unroller<Func, Derived, Start, HalfLength>::run(mat,func),
|
redux_vec_unroller<Func, Evaluator, Start, HalfLength>::template run<PacketType>(eval,func),
|
||||||
redux_vec_unroller<Func, Derived, Start+HalfLength, Length-HalfLength>::run(mat,func) );
|
redux_vec_unroller<Func, Evaluator, Start+HalfLength, Length-HalfLength>::template run<PacketType>(eval,func) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Func, typename Derived, int Start>
|
template<typename Func, typename Evaluator, int Start>
|
||||||
struct redux_vec_unroller<Func, Derived, Start, 1>
|
struct redux_vec_unroller<Func, Evaluator, Start, 1>
|
||||||
|
{
|
||||||
|
template<typename PacketType>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
static EIGEN_STRONG_INLINE PacketType run(const Evaluator &eval, const Func&)
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
index = Start * redux_traits<Func, Derived>::PacketSize,
|
PacketSize = unpacket_traits<PacketType>::size,
|
||||||
outer = index / int(Derived::InnerSizeAtCompileTime),
|
index = Start * PacketSize,
|
||||||
inner = index % int(Derived::InnerSizeAtCompileTime),
|
outer = index / int(Evaluator::InnerSizeAtCompileTime),
|
||||||
alignment = Derived::Alignment
|
inner = index % int(Evaluator::InnerSizeAtCompileTime),
|
||||||
|
alignment = Evaluator::Alignment
|
||||||
};
|
};
|
||||||
|
return eval.template packetByOuterInner<alignment,PacketType>(outer, inner);
|
||||||
typedef typename Derived::Scalar Scalar;
|
|
||||||
typedef typename redux_traits<Func, Derived>::PacketType PacketScalar;
|
|
||||||
|
|
||||||
static EIGEN_STRONG_INLINE PacketScalar run(const Derived &mat, const Func&)
|
|
||||||
{
|
|
||||||
return mat.template packetByOuterInner<alignment,PacketScalar>(outer, inner);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -176,53 +182,65 @@ struct redux_vec_unroller<Func, Derived, Start, 1>
|
||||||
* Part 3 : implementation of all cases
|
* Part 3 : implementation of all cases
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
template<typename Func, typename Derived,
|
template<typename Func, typename Evaluator,
|
||||||
int Traversal = redux_traits<Func, Derived>::Traversal,
|
int Traversal = redux_traits<Func, Evaluator>::Traversal,
|
||||||
int Unrolling = redux_traits<Func, Derived>::Unrolling
|
int Unrolling = redux_traits<Func, Evaluator>::Unrolling
|
||||||
>
|
>
|
||||||
struct redux_impl;
|
struct redux_impl;
|
||||||
|
|
||||||
template<typename Func, typename Derived>
|
template<typename Func, typename Evaluator>
|
||||||
struct redux_impl<Func, Derived, DefaultTraversal, NoUnrolling>
|
struct redux_impl<Func, Evaluator, DefaultTraversal, NoUnrolling>
|
||||||
{
|
{
|
||||||
typedef typename Derived::Scalar Scalar;
|
typedef typename Evaluator::Scalar Scalar;
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func& func)
|
template<typename XprType>
|
||||||
|
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE
|
||||||
|
Scalar run(const Evaluator &eval, const Func& func, const XprType& xpr)
|
||||||
{
|
{
|
||||||
eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix");
|
eigen_assert(xpr.rows()>0 && xpr.cols()>0 && "you are using an empty matrix");
|
||||||
Scalar res;
|
Scalar res;
|
||||||
res = mat.coeffByOuterInner(0, 0);
|
res = eval.coeffByOuterInner(0, 0);
|
||||||
for(Index i = 1; i < mat.innerSize(); ++i)
|
for(Index i = 1; i < xpr.innerSize(); ++i)
|
||||||
res = func(res, mat.coeffByOuterInner(0, i));
|
res = func(res, eval.coeffByOuterInner(0, i));
|
||||||
for(Index i = 1; i < mat.outerSize(); ++i)
|
for(Index i = 1; i < xpr.outerSize(); ++i)
|
||||||
for(Index j = 0; j < mat.innerSize(); ++j)
|
for(Index j = 0; j < xpr.innerSize(); ++j)
|
||||||
res = func(res, mat.coeffByOuterInner(i, j));
|
res = func(res, eval.coeffByOuterInner(i, j));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Func, typename Derived>
|
template<typename Func, typename Evaluator>
|
||||||
struct redux_impl<Func,Derived, DefaultTraversal, CompleteUnrolling>
|
struct redux_impl<Func,Evaluator, DefaultTraversal, CompleteUnrolling>
|
||||||
: public redux_novec_unroller<Func,Derived, 0, Derived::SizeAtCompileTime>
|
: redux_novec_unroller<Func,Evaluator, 0, Evaluator::SizeAtCompileTime>
|
||||||
{};
|
|
||||||
|
|
||||||
template<typename Func, typename Derived>
|
|
||||||
struct redux_impl<Func, Derived, LinearVectorizedTraversal, NoUnrolling>
|
|
||||||
{
|
{
|
||||||
typedef typename Derived::Scalar Scalar;
|
typedef redux_novec_unroller<Func,Evaluator, 0, Evaluator::SizeAtCompileTime> Base;
|
||||||
typedef typename redux_traits<Func, Derived>::PacketType PacketScalar;
|
typedef typename Evaluator::Scalar Scalar;
|
||||||
|
template<typename XprType>
|
||||||
static Scalar run(const Derived &mat, const Func& func)
|
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE
|
||||||
|
Scalar run(const Evaluator &eval, const Func& func, const XprType& /*xpr*/)
|
||||||
{
|
{
|
||||||
const Index size = mat.size();
|
return Base::run(eval,func);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const Index packetSize = redux_traits<Func, Derived>::PacketSize;
|
template<typename Func, typename Evaluator>
|
||||||
|
struct redux_impl<Func, Evaluator, LinearVectorizedTraversal, NoUnrolling>
|
||||||
|
{
|
||||||
|
typedef typename Evaluator::Scalar Scalar;
|
||||||
|
typedef typename redux_traits<Func, Evaluator>::PacketType PacketScalar;
|
||||||
|
|
||||||
|
template<typename XprType>
|
||||||
|
static Scalar run(const Evaluator &eval, const Func& func, const XprType& xpr)
|
||||||
|
{
|
||||||
|
const Index size = xpr.size();
|
||||||
|
|
||||||
|
const Index packetSize = redux_traits<Func, Evaluator>::PacketSize;
|
||||||
const int packetAlignment = unpacket_traits<PacketScalar>::alignment;
|
const int packetAlignment = unpacket_traits<PacketScalar>::alignment;
|
||||||
enum {
|
enum {
|
||||||
alignment0 = (bool(Derived::Flags & DirectAccessBit) && bool(packet_traits<Scalar>::AlignedOnScalar)) ? int(packetAlignment) : int(Unaligned),
|
alignment0 = (bool(Evaluator::Flags & DirectAccessBit) && bool(packet_traits<Scalar>::AlignedOnScalar)) ? int(packetAlignment) : int(Unaligned),
|
||||||
alignment = EIGEN_PLAIN_ENUM_MAX(alignment0, Derived::Alignment)
|
alignment = EIGEN_PLAIN_ENUM_MAX(alignment0, Evaluator::Alignment)
|
||||||
};
|
};
|
||||||
const Index alignedStart = internal::first_default_aligned(mat.nestedExpression());
|
const Index alignedStart = internal::first_default_aligned(xpr);
|
||||||
const Index alignedSize2 = ((size-alignedStart)/(2*packetSize))*(2*packetSize);
|
const Index alignedSize2 = ((size-alignedStart)/(2*packetSize))*(2*packetSize);
|
||||||
const Index alignedSize = ((size-alignedStart)/(packetSize))*(packetSize);
|
const Index alignedSize = ((size-alignedStart)/(packetSize))*(packetSize);
|
||||||
const Index alignedEnd2 = alignedStart + alignedSize2;
|
const Index alignedEnd2 = alignedStart + alignedSize2;
|
||||||
|
|
@ -230,34 +248,34 @@ struct redux_impl<Func, Derived, LinearVectorizedTraversal, NoUnrolling>
|
||||||
Scalar res;
|
Scalar res;
|
||||||
if(alignedSize)
|
if(alignedSize)
|
||||||
{
|
{
|
||||||
PacketScalar packet_res0 = mat.template packet<alignment,PacketScalar>(alignedStart);
|
PacketScalar packet_res0 = eval.template packet<alignment,PacketScalar>(alignedStart);
|
||||||
if(alignedSize>packetSize) // we have at least two packets to partly unroll the loop
|
if(alignedSize>packetSize) // we have at least two packets to partly unroll the loop
|
||||||
{
|
{
|
||||||
PacketScalar packet_res1 = mat.template packet<alignment,PacketScalar>(alignedStart+packetSize);
|
PacketScalar packet_res1 = eval.template packet<alignment,PacketScalar>(alignedStart+packetSize);
|
||||||
for(Index index = alignedStart + 2*packetSize; index < alignedEnd2; index += 2*packetSize)
|
for(Index index = alignedStart + 2*packetSize; index < alignedEnd2; index += 2*packetSize)
|
||||||
{
|
{
|
||||||
packet_res0 = func.packetOp(packet_res0, mat.template packet<alignment,PacketScalar>(index));
|
packet_res0 = func.packetOp(packet_res0, eval.template packet<alignment,PacketScalar>(index));
|
||||||
packet_res1 = func.packetOp(packet_res1, mat.template packet<alignment,PacketScalar>(index+packetSize));
|
packet_res1 = func.packetOp(packet_res1, eval.template packet<alignment,PacketScalar>(index+packetSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
packet_res0 = func.packetOp(packet_res0,packet_res1);
|
packet_res0 = func.packetOp(packet_res0,packet_res1);
|
||||||
if(alignedEnd>alignedEnd2)
|
if(alignedEnd>alignedEnd2)
|
||||||
packet_res0 = func.packetOp(packet_res0, mat.template packet<alignment,PacketScalar>(alignedEnd2));
|
packet_res0 = func.packetOp(packet_res0, eval.template packet<alignment,PacketScalar>(alignedEnd2));
|
||||||
}
|
}
|
||||||
res = func.predux(packet_res0);
|
res = func.predux(packet_res0);
|
||||||
|
|
||||||
for(Index index = 0; index < alignedStart; ++index)
|
for(Index index = 0; index < alignedStart; ++index)
|
||||||
res = func(res,mat.coeff(index));
|
res = func(res,eval.coeff(index));
|
||||||
|
|
||||||
for(Index index = alignedEnd; index < size; ++index)
|
for(Index index = alignedEnd; index < size; ++index)
|
||||||
res = func(res,mat.coeff(index));
|
res = func(res,eval.coeff(index));
|
||||||
}
|
}
|
||||||
else // too small to vectorize anything.
|
else // too small to vectorize anything.
|
||||||
// since this is dynamic-size hence inefficient anyway for such small sizes, don't try to optimize.
|
// since this is dynamic-size hence inefficient anyway for such small sizes, don't try to optimize.
|
||||||
{
|
{
|
||||||
res = mat.coeff(0);
|
res = eval.coeff(0);
|
||||||
for(Index index = 1; index < size; ++index)
|
for(Index index = 1; index < size; ++index)
|
||||||
res = func(res,mat.coeff(index));
|
res = func(res,eval.coeff(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
@ -265,130 +283,108 @@ struct redux_impl<Func, Derived, LinearVectorizedTraversal, NoUnrolling>
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOTE: for SliceVectorizedTraversal we simply bypass unrolling
|
// NOTE: for SliceVectorizedTraversal we simply bypass unrolling
|
||||||
template<typename Func, typename Derived, int Unrolling>
|
template<typename Func, typename Evaluator, int Unrolling>
|
||||||
struct redux_impl<Func, Derived, SliceVectorizedTraversal, Unrolling>
|
struct redux_impl<Func, Evaluator, SliceVectorizedTraversal, Unrolling>
|
||||||
{
|
{
|
||||||
typedef typename Derived::Scalar Scalar;
|
typedef typename Evaluator::Scalar Scalar;
|
||||||
typedef typename redux_traits<Func, Derived>::PacketType PacketType;
|
typedef typename redux_traits<Func, Evaluator>::PacketType PacketType;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC static Scalar run(const Derived &mat, const Func& func)
|
template<typename XprType>
|
||||||
|
EIGEN_DEVICE_FUNC static Scalar run(const Evaluator &eval, const Func& func, const XprType& xpr)
|
||||||
{
|
{
|
||||||
eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix");
|
eigen_assert(xpr.rows()>0 && xpr.cols()>0 && "you are using an empty matrix");
|
||||||
const Index innerSize = mat.innerSize();
|
const Index innerSize = xpr.innerSize();
|
||||||
const Index outerSize = mat.outerSize();
|
const Index outerSize = xpr.outerSize();
|
||||||
enum {
|
enum {
|
||||||
packetSize = redux_traits<Func, Derived>::PacketSize
|
packetSize = redux_traits<Func, Evaluator>::PacketSize
|
||||||
};
|
};
|
||||||
const Index packetedInnerSize = ((innerSize)/packetSize)*packetSize;
|
const Index packetedInnerSize = ((innerSize)/packetSize)*packetSize;
|
||||||
Scalar res;
|
Scalar res;
|
||||||
if(packetedInnerSize)
|
if(packetedInnerSize)
|
||||||
{
|
{
|
||||||
PacketType packet_res = mat.template packet<Unaligned,PacketType>(0,0);
|
PacketType packet_res = eval.template packet<Unaligned,PacketType>(0,0);
|
||||||
for(Index j=0; j<outerSize; ++j)
|
for(Index j=0; j<outerSize; ++j)
|
||||||
for(Index i=(j==0?packetSize:0); i<packetedInnerSize; i+=Index(packetSize))
|
for(Index i=(j==0?packetSize:0); i<packetedInnerSize; i+=Index(packetSize))
|
||||||
packet_res = func.packetOp(packet_res, mat.template packetByOuterInner<Unaligned,PacketType>(j,i));
|
packet_res = func.packetOp(packet_res, eval.template packetByOuterInner<Unaligned,PacketType>(j,i));
|
||||||
|
|
||||||
res = func.predux(packet_res);
|
res = func.predux(packet_res);
|
||||||
for(Index j=0; j<outerSize; ++j)
|
for(Index j=0; j<outerSize; ++j)
|
||||||
for(Index i=packetedInnerSize; i<innerSize; ++i)
|
for(Index i=packetedInnerSize; i<innerSize; ++i)
|
||||||
res = func(res, mat.coeffByOuterInner(j,i));
|
res = func(res, eval.coeffByOuterInner(j,i));
|
||||||
}
|
}
|
||||||
else // too small to vectorize anything.
|
else // too small to vectorize anything.
|
||||||
// since this is dynamic-size hence inefficient anyway for such small sizes, don't try to optimize.
|
// since this is dynamic-size hence inefficient anyway for such small sizes, don't try to optimize.
|
||||||
{
|
{
|
||||||
res = redux_impl<Func, Derived, DefaultTraversal, NoUnrolling>::run(mat, func);
|
res = redux_impl<Func, Evaluator, DefaultTraversal, NoUnrolling>::run(eval, func, xpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Func, typename Derived>
|
template<typename Func, typename Evaluator>
|
||||||
struct redux_impl<Func, Derived, LinearVectorizedTraversal, CompleteUnrolling>
|
struct redux_impl<Func, Evaluator, LinearVectorizedTraversal, CompleteUnrolling>
|
||||||
{
|
{
|
||||||
typedef typename Derived::Scalar Scalar;
|
typedef typename Evaluator::Scalar Scalar;
|
||||||
|
|
||||||
typedef typename redux_traits<Func, Derived>::PacketType PacketScalar;
|
typedef typename redux_traits<Func, Evaluator>::PacketType PacketType;
|
||||||
enum {
|
enum {
|
||||||
PacketSize = redux_traits<Func, Derived>::PacketSize,
|
PacketSize = redux_traits<Func, Evaluator>::PacketSize,
|
||||||
Size = Derived::SizeAtCompileTime,
|
Size = Evaluator::SizeAtCompileTime,
|
||||||
VectorizedSize = (Size / PacketSize) * PacketSize
|
VectorizedSize = (int(Size) / int(PacketSize)) * int(PacketSize)
|
||||||
};
|
};
|
||||||
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func& func)
|
|
||||||
|
template<typename XprType>
|
||||||
|
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE
|
||||||
|
Scalar run(const Evaluator &eval, const Func& func, const XprType &xpr)
|
||||||
{
|
{
|
||||||
eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix");
|
EIGEN_ONLY_USED_FOR_DEBUG(xpr)
|
||||||
|
eigen_assert(xpr.rows()>0 && xpr.cols()>0 && "you are using an empty matrix");
|
||||||
if (VectorizedSize > 0) {
|
if (VectorizedSize > 0) {
|
||||||
Scalar res = func.predux(redux_vec_unroller<Func, Derived, 0, Size / PacketSize>::run(mat,func));
|
Scalar res = func.predux(redux_vec_unroller<Func, Evaluator, 0, Size / PacketSize>::template run<PacketType>(eval,func));
|
||||||
if (VectorizedSize != Size)
|
if (VectorizedSize != Size)
|
||||||
res = func(res,redux_novec_unroller<Func, Derived, VectorizedSize, Size-VectorizedSize>::run(mat,func));
|
res = func(res,redux_novec_unroller<Func, Evaluator, VectorizedSize, Size-VectorizedSize>::run(eval,func));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return redux_novec_unroller<Func, Derived, 0, Size>::run(mat,func);
|
return redux_novec_unroller<Func, Evaluator, 0, Size>::run(eval,func);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// evaluator adaptor
|
// evaluator adaptor
|
||||||
template<typename _XprType>
|
template<typename _XprType>
|
||||||
class redux_evaluator
|
class redux_evaluator : public internal::evaluator<_XprType>
|
||||||
{
|
{
|
||||||
|
typedef internal::evaluator<_XprType> Base;
|
||||||
public:
|
public:
|
||||||
typedef _XprType XprType;
|
typedef _XprType XprType;
|
||||||
EIGEN_DEVICE_FUNC explicit redux_evaluator(const XprType &xpr) : m_evaluator(xpr), m_xpr(xpr) {}
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
explicit redux_evaluator(const XprType &xpr) : Base(xpr) {}
|
||||||
|
|
||||||
typedef typename XprType::Scalar Scalar;
|
typedef typename XprType::Scalar Scalar;
|
||||||
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
||||||
typedef typename XprType::PacketScalar PacketScalar;
|
typedef typename XprType::PacketScalar PacketScalar;
|
||||||
typedef typename XprType::PacketReturnType PacketReturnType;
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MaxRowsAtCompileTime = XprType::MaxRowsAtCompileTime,
|
MaxRowsAtCompileTime = XprType::MaxRowsAtCompileTime,
|
||||||
MaxColsAtCompileTime = XprType::MaxColsAtCompileTime,
|
MaxColsAtCompileTime = XprType::MaxColsAtCompileTime,
|
||||||
// TODO we should not remove DirectAccessBit and rather find an elegant way to query the alignment offset at runtime from the evaluator
|
// TODO we should not remove DirectAccessBit and rather find an elegant way to query the alignment offset at runtime from the evaluator
|
||||||
Flags = evaluator<XprType>::Flags & ~DirectAccessBit,
|
Flags = Base::Flags & ~DirectAccessBit,
|
||||||
IsRowMajor = XprType::IsRowMajor,
|
IsRowMajor = XprType::IsRowMajor,
|
||||||
SizeAtCompileTime = XprType::SizeAtCompileTime,
|
SizeAtCompileTime = XprType::SizeAtCompileTime,
|
||||||
InnerSizeAtCompileTime = XprType::InnerSizeAtCompileTime,
|
InnerSizeAtCompileTime = XprType::InnerSizeAtCompileTime
|
||||||
CoeffReadCost = evaluator<XprType>::CoeffReadCost,
|
|
||||||
Alignment = evaluator<XprType>::Alignment
|
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC Index rows() const { return m_xpr.rows(); }
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
EIGEN_DEVICE_FUNC Index cols() const { return m_xpr.cols(); }
|
|
||||||
EIGEN_DEVICE_FUNC Index size() const { return m_xpr.size(); }
|
|
||||||
EIGEN_DEVICE_FUNC Index innerSize() const { return m_xpr.innerSize(); }
|
|
||||||
EIGEN_DEVICE_FUNC Index outerSize() const { return m_xpr.outerSize(); }
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
CoeffReturnType coeff(Index row, Index col) const
|
|
||||||
{ return m_evaluator.coeff(row, col); }
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
CoeffReturnType coeff(Index index) const
|
|
||||||
{ return m_evaluator.coeff(index); }
|
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
|
||||||
PacketType packet(Index row, Index col) const
|
|
||||||
{ return m_evaluator.template packet<LoadMode,PacketType>(row, col); }
|
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
|
||||||
PacketType packet(Index index) const
|
|
||||||
{ return m_evaluator.template packet<LoadMode,PacketType>(index); }
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
CoeffReturnType coeffByOuterInner(Index outer, Index inner) const
|
CoeffReturnType coeffByOuterInner(Index outer, Index inner) const
|
||||||
{ return m_evaluator.coeff(IsRowMajor ? outer : inner, IsRowMajor ? inner : outer); }
|
{ return Base::coeff(IsRowMajor ? outer : inner, IsRowMajor ? inner : outer); }
|
||||||
|
|
||||||
template<int LoadMode, typename PacketType>
|
template<int LoadMode, typename PacketType>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
PacketType packetByOuterInner(Index outer, Index inner) const
|
PacketType packetByOuterInner(Index outer, Index inner) const
|
||||||
{ return m_evaluator.template packet<LoadMode,PacketType>(IsRowMajor ? outer : inner, IsRowMajor ? inner : outer); }
|
{ return Base::template packet<LoadMode,PacketType>(IsRowMajor ? outer : inner, IsRowMajor ? inner : outer); }
|
||||||
|
|
||||||
const XprType & nestedExpression() const { return m_xpr; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
internal::evaluator<XprType> m_evaluator;
|
|
||||||
const XprType &m_xpr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
@ -403,11 +399,13 @@ protected:
|
||||||
* The template parameter \a BinaryOp is the type of the functor \a func which must be
|
* The template parameter \a BinaryOp is the type of the functor \a func which must be
|
||||||
* an associative operator. Both current C++98 and C++11 functor styles are handled.
|
* an associative operator. Both current C++98 and C++11 functor styles are handled.
|
||||||
*
|
*
|
||||||
|
* \warning the matrix must be not empty, otherwise an assertion is triggered.
|
||||||
|
*
|
||||||
* \sa DenseBase::sum(), DenseBase::minCoeff(), DenseBase::maxCoeff(), MatrixBase::colwise(), MatrixBase::rowwise()
|
* \sa DenseBase::sum(), DenseBase::minCoeff(), DenseBase::maxCoeff(), MatrixBase::colwise(), MatrixBase::rowwise()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename Func>
|
template<typename Func>
|
||||||
EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
||||||
DenseBase<Derived>::redux(const Func& func) const
|
DenseBase<Derived>::redux(const Func& func) const
|
||||||
{
|
{
|
||||||
eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
|
eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
|
||||||
|
|
@ -415,27 +413,39 @@ DenseBase<Derived>::redux(const Func& func) const
|
||||||
typedef typename internal::redux_evaluator<Derived> ThisEvaluator;
|
typedef typename internal::redux_evaluator<Derived> ThisEvaluator;
|
||||||
ThisEvaluator thisEval(derived());
|
ThisEvaluator thisEval(derived());
|
||||||
|
|
||||||
return internal::redux_impl<Func, ThisEvaluator>::run(thisEval, func);
|
// The initial expression is passed to the reducer as an additional argument instead of
|
||||||
|
// passing it as a member of redux_evaluator to help
|
||||||
|
return internal::redux_impl<Func, ThisEvaluator>::run(thisEval, func, derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the minimum of all coefficients of \c *this.
|
/** \returns the minimum of all coefficients of \c *this.
|
||||||
* \warning the result is undefined if \c *this contains NaN.
|
* In case \c *this contains NaN, NaNPropagation determines the behavior:
|
||||||
|
* NaNPropagation == PropagateFast : undefined
|
||||||
|
* NaNPropagation == PropagateNaN : result is NaN
|
||||||
|
* NaNPropagation == PropagateNumbers : result is minimum of elements that are not NaN
|
||||||
|
* \warning the matrix must be not empty, otherwise an assertion is triggered.
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
template<int NaNPropagation>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
||||||
DenseBase<Derived>::minCoeff() const
|
DenseBase<Derived>::minCoeff() const
|
||||||
{
|
{
|
||||||
return derived().redux(Eigen::internal::scalar_min_op<Scalar,Scalar>());
|
return derived().redux(Eigen::internal::scalar_min_op<Scalar,Scalar, NaNPropagation>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the maximum of all coefficients of \c *this.
|
/** \returns the maximum of all coefficients of \c *this.
|
||||||
* \warning the result is undefined if \c *this contains NaN.
|
* In case \c *this contains NaN, NaNPropagation determines the behavior:
|
||||||
|
* NaNPropagation == PropagateFast : undefined
|
||||||
|
* NaNPropagation == PropagateNaN : result is NaN
|
||||||
|
* NaNPropagation == PropagateNumbers : result is maximum of elements that are not NaN
|
||||||
|
* \warning the matrix must be not empty, otherwise an assertion is triggered.
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
template<int NaNPropagation>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
||||||
DenseBase<Derived>::maxCoeff() const
|
DenseBase<Derived>::maxCoeff() const
|
||||||
{
|
{
|
||||||
return derived().redux(Eigen::internal::scalar_max_op<Scalar,Scalar>());
|
return derived().redux(Eigen::internal::scalar_max_op<Scalar,Scalar, NaNPropagation>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the sum of all coefficients of \c *this
|
/** \returns the sum of all coefficients of \c *this
|
||||||
|
|
@ -445,7 +455,7 @@ DenseBase<Derived>::maxCoeff() const
|
||||||
* \sa trace(), prod(), mean()
|
* \sa trace(), prod(), mean()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
||||||
DenseBase<Derived>::sum() const
|
DenseBase<Derived>::sum() const
|
||||||
{
|
{
|
||||||
if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0))
|
if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0))
|
||||||
|
|
@ -458,7 +468,7 @@ DenseBase<Derived>::sum() const
|
||||||
* \sa trace(), prod(), sum()
|
* \sa trace(), prod(), sum()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
||||||
DenseBase<Derived>::mean() const
|
DenseBase<Derived>::mean() const
|
||||||
{
|
{
|
||||||
#ifdef __INTEL_COMPILER
|
#ifdef __INTEL_COMPILER
|
||||||
|
|
@ -479,7 +489,7 @@ DenseBase<Derived>::mean() const
|
||||||
* \sa sum(), mean(), trace()
|
* \sa sum(), mean(), trace()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
||||||
DenseBase<Derived>::prod() const
|
DenseBase<Derived>::prod() const
|
||||||
{
|
{
|
||||||
if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0))
|
if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0))
|
||||||
|
|
@ -494,7 +504,7 @@ DenseBase<Derived>::prod() const
|
||||||
* \sa diagonal(), sum()
|
* \sa diagonal(), sum()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
||||||
MatrixBase<Derived>::trace() const
|
MatrixBase<Derived>::trace() const
|
||||||
{
|
{
|
||||||
return derived().diagonal().sum();
|
return derived().diagonal().sum();
|
||||||
|
|
|
||||||
|
|
@ -28,12 +28,13 @@ struct traits<Ref<_PlainObjectType, _Options, _StrideType> >
|
||||||
|
|
||||||
template<typename Derived> struct match {
|
template<typename Derived> struct match {
|
||||||
enum {
|
enum {
|
||||||
|
IsVectorAtCompileTime = PlainObjectType::IsVectorAtCompileTime || Derived::IsVectorAtCompileTime,
|
||||||
HasDirectAccess = internal::has_direct_access<Derived>::ret,
|
HasDirectAccess = internal::has_direct_access<Derived>::ret,
|
||||||
StorageOrderMatch = PlainObjectType::IsVectorAtCompileTime || Derived::IsVectorAtCompileTime || ((PlainObjectType::Flags&RowMajorBit)==(Derived::Flags&RowMajorBit)),
|
StorageOrderMatch = IsVectorAtCompileTime || ((PlainObjectType::Flags&RowMajorBit)==(Derived::Flags&RowMajorBit)),
|
||||||
InnerStrideMatch = int(StrideType::InnerStrideAtCompileTime)==int(Dynamic)
|
InnerStrideMatch = int(StrideType::InnerStrideAtCompileTime)==int(Dynamic)
|
||||||
|| int(StrideType::InnerStrideAtCompileTime)==int(Derived::InnerStrideAtCompileTime)
|
|| int(StrideType::InnerStrideAtCompileTime)==int(Derived::InnerStrideAtCompileTime)
|
||||||
|| (int(StrideType::InnerStrideAtCompileTime)==0 && int(Derived::InnerStrideAtCompileTime)==1),
|
|| (int(StrideType::InnerStrideAtCompileTime)==0 && int(Derived::InnerStrideAtCompileTime)==1),
|
||||||
OuterStrideMatch = Derived::IsVectorAtCompileTime
|
OuterStrideMatch = IsVectorAtCompileTime
|
||||||
|| int(StrideType::OuterStrideAtCompileTime)==int(Dynamic) || int(StrideType::OuterStrideAtCompileTime)==int(Derived::OuterStrideAtCompileTime),
|
|| int(StrideType::OuterStrideAtCompileTime)==int(Dynamic) || int(StrideType::OuterStrideAtCompileTime)==int(Derived::OuterStrideAtCompileTime),
|
||||||
// NOTE, this indirection of evaluator<Derived>::Alignment is needed
|
// NOTE, this indirection of evaluator<Derived>::Alignment is needed
|
||||||
// to workaround a very strange bug in MSVC related to the instantiation
|
// to workaround a very strange bug in MSVC related to the instantiation
|
||||||
|
|
@ -66,12 +67,12 @@ public:
|
||||||
typedef MapBase<Derived> Base;
|
typedef MapBase<Derived> Base;
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE(RefBase)
|
EIGEN_DENSE_PUBLIC_INTERFACE(RefBase)
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline Index innerStride() const
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index innerStride() const
|
||||||
{
|
{
|
||||||
return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
|
return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline Index outerStride() const
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index outerStride() const
|
||||||
{
|
{
|
||||||
return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
|
return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
|
||||||
: IsVectorAtCompileTime ? this->size()
|
: IsVectorAtCompileTime ? this->size()
|
||||||
|
|
@ -92,29 +93,115 @@ protected:
|
||||||
|
|
||||||
typedef Stride<StrideType::OuterStrideAtCompileTime,StrideType::InnerStrideAtCompileTime> StrideBase;
|
typedef Stride<StrideType::OuterStrideAtCompileTime,StrideType::InnerStrideAtCompileTime> StrideBase;
|
||||||
|
|
||||||
template<typename Expression>
|
// Resolves inner stride if default 0.
|
||||||
EIGEN_DEVICE_FUNC void construct(Expression& expr)
|
static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index resolveInnerStride(Index inner) {
|
||||||
{
|
return inner == 0 ? 1 : inner;
|
||||||
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(PlainObjectType,Expression);
|
}
|
||||||
|
|
||||||
|
// Resolves outer stride if default 0.
|
||||||
|
static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index resolveOuterStride(Index inner, Index outer, Index rows, Index cols, bool isVectorAtCompileTime, bool isRowMajor) {
|
||||||
|
return outer == 0 ? isVectorAtCompileTime ? inner * rows * cols : isRowMajor ? inner * cols : inner * rows : outer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if construction is valid, false if there is a stride mismatch,
|
||||||
|
// and fails if there is a size mismatch.
|
||||||
|
template<typename Expression>
|
||||||
|
EIGEN_DEVICE_FUNC bool construct(Expression& expr)
|
||||||
|
{
|
||||||
|
// Check matrix sizes. If this is a compile-time vector, we do allow
|
||||||
|
// implicitly transposing.
|
||||||
|
EIGEN_STATIC_ASSERT(
|
||||||
|
EIGEN_PREDICATE_SAME_MATRIX_SIZE(PlainObjectType, Expression)
|
||||||
|
// If it is a vector, the transpose sizes might match.
|
||||||
|
|| ( PlainObjectType::IsVectorAtCompileTime
|
||||||
|
&& ((int(PlainObjectType::RowsAtCompileTime)==Eigen::Dynamic
|
||||||
|
|| int(Expression::ColsAtCompileTime)==Eigen::Dynamic
|
||||||
|
|| int(PlainObjectType::RowsAtCompileTime)==int(Expression::ColsAtCompileTime))
|
||||||
|
&& (int(PlainObjectType::ColsAtCompileTime)==Eigen::Dynamic
|
||||||
|
|| int(Expression::RowsAtCompileTime)==Eigen::Dynamic
|
||||||
|
|| int(PlainObjectType::ColsAtCompileTime)==int(Expression::RowsAtCompileTime)))),
|
||||||
|
YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES
|
||||||
|
)
|
||||||
|
|
||||||
|
// Determine runtime rows and columns.
|
||||||
|
Index rows = expr.rows();
|
||||||
|
Index cols = expr.cols();
|
||||||
if(PlainObjectType::RowsAtCompileTime==1)
|
if(PlainObjectType::RowsAtCompileTime==1)
|
||||||
{
|
{
|
||||||
eigen_assert(expr.rows()==1 || expr.cols()==1);
|
eigen_assert(expr.rows()==1 || expr.cols()==1);
|
||||||
::new (static_cast<Base*>(this)) Base(expr.data(), 1, expr.size());
|
rows = 1;
|
||||||
|
cols = expr.size();
|
||||||
}
|
}
|
||||||
else if(PlainObjectType::ColsAtCompileTime==1)
|
else if(PlainObjectType::ColsAtCompileTime==1)
|
||||||
{
|
{
|
||||||
eigen_assert(expr.rows()==1 || expr.cols()==1);
|
eigen_assert(expr.rows()==1 || expr.cols()==1);
|
||||||
::new (static_cast<Base*>(this)) Base(expr.data(), expr.size(), 1);
|
rows = expr.size();
|
||||||
|
cols = 1;
|
||||||
}
|
}
|
||||||
else
|
// Verify that the sizes are valid.
|
||||||
::new (static_cast<Base*>(this)) Base(expr.data(), expr.rows(), expr.cols());
|
eigen_assert(
|
||||||
|
(PlainObjectType::RowsAtCompileTime == Dynamic) || (PlainObjectType::RowsAtCompileTime == rows));
|
||||||
|
eigen_assert(
|
||||||
|
(PlainObjectType::ColsAtCompileTime == Dynamic) || (PlainObjectType::ColsAtCompileTime == cols));
|
||||||
|
|
||||||
if(Expression::IsVectorAtCompileTime && (!PlainObjectType::IsVectorAtCompileTime) && ((Expression::Flags&RowMajorBit)!=(PlainObjectType::Flags&RowMajorBit)))
|
|
||||||
::new (&m_stride) StrideBase(expr.innerStride(), StrideType::InnerStrideAtCompileTime==0?0:1);
|
// If this is a vector, we might be transposing, which means that stride should swap.
|
||||||
else
|
const bool transpose = PlainObjectType::IsVectorAtCompileTime && (rows != expr.rows());
|
||||||
::new (&m_stride) StrideBase(StrideType::OuterStrideAtCompileTime==0?0:expr.outerStride(),
|
// If the storage format differs, we also need to swap the stride.
|
||||||
StrideType::InnerStrideAtCompileTime==0?0:expr.innerStride());
|
const bool row_major = ((PlainObjectType::Flags)&RowMajorBit) != 0;
|
||||||
|
const bool expr_row_major = (Expression::Flags&RowMajorBit) != 0;
|
||||||
|
const bool storage_differs = (row_major != expr_row_major);
|
||||||
|
|
||||||
|
const bool swap_stride = (transpose != storage_differs);
|
||||||
|
|
||||||
|
// Determine expr's actual strides, resolving any defaults if zero.
|
||||||
|
const Index expr_inner_actual = resolveInnerStride(expr.innerStride());
|
||||||
|
const Index expr_outer_actual = resolveOuterStride(expr_inner_actual,
|
||||||
|
expr.outerStride(),
|
||||||
|
expr.rows(),
|
||||||
|
expr.cols(),
|
||||||
|
Expression::IsVectorAtCompileTime != 0,
|
||||||
|
expr_row_major);
|
||||||
|
|
||||||
|
// If this is a column-major row vector or row-major column vector, the inner-stride
|
||||||
|
// is arbitrary, so set it to either the compile-time inner stride or 1.
|
||||||
|
const bool row_vector = (rows == 1);
|
||||||
|
const bool col_vector = (cols == 1);
|
||||||
|
const Index inner_stride =
|
||||||
|
( (!row_major && row_vector) || (row_major && col_vector) ) ?
|
||||||
|
( StrideType::InnerStrideAtCompileTime > 0 ? Index(StrideType::InnerStrideAtCompileTime) : 1)
|
||||||
|
: swap_stride ? expr_outer_actual : expr_inner_actual;
|
||||||
|
|
||||||
|
// If this is a column-major column vector or row-major row vector, the outer-stride
|
||||||
|
// is arbitrary, so set it to either the compile-time outer stride or vector size.
|
||||||
|
const Index outer_stride =
|
||||||
|
( (!row_major && col_vector) || (row_major && row_vector) ) ?
|
||||||
|
( StrideType::OuterStrideAtCompileTime > 0 ? Index(StrideType::OuterStrideAtCompileTime) : rows * cols * inner_stride)
|
||||||
|
: swap_stride ? expr_inner_actual : expr_outer_actual;
|
||||||
|
|
||||||
|
// Check if given inner/outer strides are compatible with compile-time strides.
|
||||||
|
const bool inner_valid = (StrideType::InnerStrideAtCompileTime == Dynamic)
|
||||||
|
|| (resolveInnerStride(Index(StrideType::InnerStrideAtCompileTime)) == inner_stride);
|
||||||
|
if (!inner_valid) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool outer_valid = (StrideType::OuterStrideAtCompileTime == Dynamic)
|
||||||
|
|| (resolveOuterStride(
|
||||||
|
inner_stride,
|
||||||
|
Index(StrideType::OuterStrideAtCompileTime),
|
||||||
|
rows, cols, PlainObjectType::IsVectorAtCompileTime != 0,
|
||||||
|
row_major)
|
||||||
|
== outer_stride);
|
||||||
|
if (!outer_valid) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
::new (static_cast<Base*>(this)) Base(expr.data(), rows, cols);
|
||||||
|
::new (&m_stride) StrideBase(
|
||||||
|
(StrideType::OuterStrideAtCompileTime == 0) ? 0 : outer_stride,
|
||||||
|
(StrideType::InnerStrideAtCompileTime == 0) ? 0 : inner_stride );
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
StrideBase m_stride;
|
StrideBase m_stride;
|
||||||
|
|
@ -186,6 +273,8 @@ protected:
|
||||||
* void foo(const Ref<MatrixXf,0,Stride<> >& A) { foo_impl(A); }
|
* void foo(const Ref<MatrixXf,0,Stride<> >& A) { foo_impl(A); }
|
||||||
* \endcode
|
* \endcode
|
||||||
*
|
*
|
||||||
|
* See also the following stackoverflow questions for further references:
|
||||||
|
* - <a href="http://stackoverflow.com/questions/21132538/correct-usage-of-the-eigenref-class">Correct usage of the Eigen::Ref<> class</a>
|
||||||
*
|
*
|
||||||
* \sa PlainObjectBase::Map(), \ref TopicStorageOrders
|
* \sa PlainObjectBase::Map(), \ref TopicStorageOrders
|
||||||
*/
|
*/
|
||||||
|
|
@ -209,7 +298,10 @@ template<typename PlainObjectType, int Options, typename StrideType> class Ref
|
||||||
typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
|
typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
|
EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
|
||||||
Base::construct(expr.derived());
|
// Construction must pass since we will not create temprary storage in the non-const case.
|
||||||
|
const bool success = Base::construct(expr.derived());
|
||||||
|
EIGEN_UNUSED_VARIABLE(success)
|
||||||
|
eigen_assert(success);
|
||||||
}
|
}
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC inline Ref(const DenseBase<Derived>& expr,
|
EIGEN_DEVICE_FUNC inline Ref(const DenseBase<Derived>& expr,
|
||||||
|
|
@ -223,7 +315,10 @@ template<typename PlainObjectType, int Options, typename StrideType> class Ref
|
||||||
EIGEN_STATIC_ASSERT(bool(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
|
EIGEN_STATIC_ASSERT(bool(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
|
||||||
EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
|
EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
|
||||||
EIGEN_STATIC_ASSERT(!Derived::IsPlainObjectBase,THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
|
EIGEN_STATIC_ASSERT(!Derived::IsPlainObjectBase,THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
|
||||||
Base::construct(expr.const_cast_derived());
|
// Construction must pass since we will not create temporary storage in the non-const case.
|
||||||
|
const bool success = Base::construct(expr.const_cast_derived());
|
||||||
|
EIGEN_UNUSED_VARIABLE(success)
|
||||||
|
eigen_assert(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Ref)
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Ref)
|
||||||
|
|
@ -264,7 +359,10 @@ template<typename TPlainObjectType, int Options, typename StrideType> class Ref<
|
||||||
template<typename Expression>
|
template<typename Expression>
|
||||||
EIGEN_DEVICE_FUNC void construct(const Expression& expr,internal::true_type)
|
EIGEN_DEVICE_FUNC void construct(const Expression& expr,internal::true_type)
|
||||||
{
|
{
|
||||||
Base::construct(expr);
|
// Check if we can use the underlying expr's storage directly, otherwise call the copy version.
|
||||||
|
if (!Base::construct(expr)) {
|
||||||
|
construct(expr, internal::false_type());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Expression>
|
template<typename Expression>
|
||||||
|
|
|
||||||
|
|
@ -88,9 +88,9 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
|
||||||
THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE)
|
THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE)
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index rows() const { return m_matrix.rows() * m_rowFactor.value(); }
|
inline Index rows() const { return m_matrix.rows() * m_rowFactor.value(); }
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index cols() const { return m_matrix.cols() * m_colFactor.value(); }
|
inline Index cols() const { return m_matrix.cols() * m_colFactor.value(); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
|
|
@ -115,7 +115,7 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<int RowFactor, int ColFactor>
|
template<int RowFactor, int ColFactor>
|
||||||
const Replicate<Derived,RowFactor,ColFactor>
|
EIGEN_DEVICE_FUNC const Replicate<Derived,RowFactor,ColFactor>
|
||||||
DenseBase<Derived>::replicate() const
|
DenseBase<Derived>::replicate() const
|
||||||
{
|
{
|
||||||
return Replicate<Derived,RowFactor,ColFactor>(derived());
|
return Replicate<Derived,RowFactor,ColFactor>(derived());
|
||||||
|
|
@ -130,7 +130,7 @@ DenseBase<Derived>::replicate() const
|
||||||
* \sa VectorwiseOp::replicate(), DenseBase::replicate(), class Replicate
|
* \sa VectorwiseOp::replicate(), DenseBase::replicate(), class Replicate
|
||||||
*/
|
*/
|
||||||
template<typename ExpressionType, int Direction>
|
template<typename ExpressionType, int Direction>
|
||||||
const typename VectorwiseOp<ExpressionType,Direction>::ReplicateReturnType
|
EIGEN_DEVICE_FUNC const typename VectorwiseOp<ExpressionType,Direction>::ReplicateReturnType
|
||||||
VectorwiseOp<ExpressionType,Direction>::replicate(Index factor) const
|
VectorwiseOp<ExpressionType,Direction>::replicate(Index factor) const
|
||||||
{
|
{
|
||||||
return typename VectorwiseOp<ExpressionType,Direction>::ReplicateReturnType
|
return typename VectorwiseOp<ExpressionType,Direction>::ReplicateReturnType
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,454 @@
|
||||||
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
|
// for linear algebra.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2008-2017 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
|
// Copyright (C) 2014 yoco <peter.xiau@gmail.com>
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the Mozilla
|
||||||
|
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||||
|
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
#ifndef EIGEN_RESHAPED_H
|
||||||
|
#define EIGEN_RESHAPED_H
|
||||||
|
|
||||||
|
namespace Eigen {
|
||||||
|
|
||||||
|
/** \class Reshaped
|
||||||
|
* \ingroup Core_Module
|
||||||
|
*
|
||||||
|
* \brief Expression of a fixed-size or dynamic-size reshape
|
||||||
|
*
|
||||||
|
* \tparam XprType the type of the expression in which we are taking a reshape
|
||||||
|
* \tparam Rows the number of rows of the reshape we are taking at compile time (optional)
|
||||||
|
* \tparam Cols the number of columns of the reshape we are taking at compile time (optional)
|
||||||
|
* \tparam Order can be ColMajor or RowMajor, default is ColMajor.
|
||||||
|
*
|
||||||
|
* This class represents an expression of either a fixed-size or dynamic-size reshape.
|
||||||
|
* It is the return type of DenseBase::reshaped(NRowsType,NColsType) and
|
||||||
|
* most of the time this is the only way it is used.
|
||||||
|
*
|
||||||
|
* However, in C++98, if you want to directly maniputate reshaped expressions,
|
||||||
|
* for instance if you want to write a function returning such an expression, you
|
||||||
|
* will need to use this class. In C++11, it is advised to use the \em auto
|
||||||
|
* keyword for such use cases.
|
||||||
|
*
|
||||||
|
* Here is an example illustrating the dynamic case:
|
||||||
|
* \include class_Reshaped.cpp
|
||||||
|
* Output: \verbinclude class_Reshaped.out
|
||||||
|
*
|
||||||
|
* Here is an example illustrating the fixed-size case:
|
||||||
|
* \include class_FixedReshaped.cpp
|
||||||
|
* Output: \verbinclude class_FixedReshaped.out
|
||||||
|
*
|
||||||
|
* \sa DenseBase::reshaped(NRowsType,NColsType)
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template<typename XprType, int Rows, int Cols, int Order>
|
||||||
|
struct traits<Reshaped<XprType, Rows, Cols, Order> > : traits<XprType>
|
||||||
|
{
|
||||||
|
typedef typename traits<XprType>::Scalar Scalar;
|
||||||
|
typedef typename traits<XprType>::StorageKind StorageKind;
|
||||||
|
typedef typename traits<XprType>::XprKind XprKind;
|
||||||
|
enum{
|
||||||
|
MatrixRows = traits<XprType>::RowsAtCompileTime,
|
||||||
|
MatrixCols = traits<XprType>::ColsAtCompileTime,
|
||||||
|
RowsAtCompileTime = Rows,
|
||||||
|
ColsAtCompileTime = Cols,
|
||||||
|
MaxRowsAtCompileTime = Rows,
|
||||||
|
MaxColsAtCompileTime = Cols,
|
||||||
|
XpxStorageOrder = ((int(traits<XprType>::Flags) & RowMajorBit) == RowMajorBit) ? RowMajor : ColMajor,
|
||||||
|
ReshapedStorageOrder = (RowsAtCompileTime == 1 && ColsAtCompileTime != 1) ? RowMajor
|
||||||
|
: (ColsAtCompileTime == 1 && RowsAtCompileTime != 1) ? ColMajor
|
||||||
|
: XpxStorageOrder,
|
||||||
|
HasSameStorageOrderAsXprType = (ReshapedStorageOrder == XpxStorageOrder),
|
||||||
|
InnerSize = (ReshapedStorageOrder==int(RowMajor)) ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
|
||||||
|
InnerStrideAtCompileTime = HasSameStorageOrderAsXprType
|
||||||
|
? int(inner_stride_at_compile_time<XprType>::ret)
|
||||||
|
: Dynamic,
|
||||||
|
OuterStrideAtCompileTime = Dynamic,
|
||||||
|
|
||||||
|
HasDirectAccess = internal::has_direct_access<XprType>::ret
|
||||||
|
&& (Order==int(XpxStorageOrder))
|
||||||
|
&& ((evaluator<XprType>::Flags&LinearAccessBit)==LinearAccessBit),
|
||||||
|
|
||||||
|
MaskPacketAccessBit = (InnerSize == Dynamic || (InnerSize % packet_traits<Scalar>::size) == 0)
|
||||||
|
&& (InnerStrideAtCompileTime == 1)
|
||||||
|
? PacketAccessBit : 0,
|
||||||
|
//MaskAlignedBit = ((OuterStrideAtCompileTime!=Dynamic) && (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % 16) == 0)) ? AlignedBit : 0,
|
||||||
|
FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0,
|
||||||
|
FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
|
||||||
|
FlagsRowMajorBit = (ReshapedStorageOrder==int(RowMajor)) ? RowMajorBit : 0,
|
||||||
|
FlagsDirectAccessBit = HasDirectAccess ? DirectAccessBit : 0,
|
||||||
|
Flags0 = traits<XprType>::Flags & ( (HereditaryBits & ~RowMajorBit) | MaskPacketAccessBit),
|
||||||
|
|
||||||
|
Flags = (Flags0 | FlagsLinearAccessBit | FlagsLvalueBit | FlagsRowMajorBit | FlagsDirectAccessBit)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename XprType, int Rows, int Cols, int Order, bool HasDirectAccess> class ReshapedImpl_dense;
|
||||||
|
|
||||||
|
} // end namespace internal
|
||||||
|
|
||||||
|
template<typename XprType, int Rows, int Cols, int Order, typename StorageKind> class ReshapedImpl;
|
||||||
|
|
||||||
|
template<typename XprType, int Rows, int Cols, int Order> class Reshaped
|
||||||
|
: public ReshapedImpl<XprType, Rows, Cols, Order, typename internal::traits<XprType>::StorageKind>
|
||||||
|
{
|
||||||
|
typedef ReshapedImpl<XprType, Rows, Cols, Order, typename internal::traits<XprType>::StorageKind> Impl;
|
||||||
|
public:
|
||||||
|
//typedef typename Impl::Base Base;
|
||||||
|
typedef Impl Base;
|
||||||
|
EIGEN_GENERIC_PUBLIC_INTERFACE(Reshaped)
|
||||||
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reshaped)
|
||||||
|
|
||||||
|
/** Fixed-size constructor
|
||||||
|
*/
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
inline Reshaped(XprType& xpr)
|
||||||
|
: Impl(xpr)
|
||||||
|
{
|
||||||
|
EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
|
||||||
|
eigen_assert(Rows * Cols == xpr.rows() * xpr.cols());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Dynamic-size constructor
|
||||||
|
*/
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
inline Reshaped(XprType& xpr,
|
||||||
|
Index reshapeRows, Index reshapeCols)
|
||||||
|
: Impl(xpr, reshapeRows, reshapeCols)
|
||||||
|
{
|
||||||
|
eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==reshapeRows)
|
||||||
|
&& (ColsAtCompileTime==Dynamic || ColsAtCompileTime==reshapeCols));
|
||||||
|
eigen_assert(reshapeRows * reshapeCols == xpr.rows() * xpr.cols());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// The generic default implementation for dense reshape simply forward to the internal::ReshapedImpl_dense
|
||||||
|
// that must be specialized for direct and non-direct access...
|
||||||
|
template<typename XprType, int Rows, int Cols, int Order>
|
||||||
|
class ReshapedImpl<XprType, Rows, Cols, Order, Dense>
|
||||||
|
: public internal::ReshapedImpl_dense<XprType, Rows, Cols, Order,internal::traits<Reshaped<XprType,Rows,Cols,Order> >::HasDirectAccess>
|
||||||
|
{
|
||||||
|
typedef internal::ReshapedImpl_dense<XprType, Rows, Cols, Order,internal::traits<Reshaped<XprType,Rows,Cols,Order> >::HasDirectAccess> Impl;
|
||||||
|
public:
|
||||||
|
typedef Impl Base;
|
||||||
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ReshapedImpl)
|
||||||
|
EIGEN_DEVICE_FUNC inline ReshapedImpl(XprType& xpr) : Impl(xpr) {}
|
||||||
|
EIGEN_DEVICE_FUNC inline ReshapedImpl(XprType& xpr, Index reshapeRows, Index reshapeCols)
|
||||||
|
: Impl(xpr, reshapeRows, reshapeCols) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
/** \internal Internal implementation of dense Reshaped in the general case. */
|
||||||
|
template<typename XprType, int Rows, int Cols, int Order>
|
||||||
|
class ReshapedImpl_dense<XprType,Rows,Cols,Order,false>
|
||||||
|
: public internal::dense_xpr_base<Reshaped<XprType, Rows, Cols, Order> >::type
|
||||||
|
{
|
||||||
|
typedef Reshaped<XprType, Rows, Cols, Order> ReshapedType;
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef typename internal::dense_xpr_base<ReshapedType>::type Base;
|
||||||
|
EIGEN_DENSE_PUBLIC_INTERFACE(ReshapedType)
|
||||||
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ReshapedImpl_dense)
|
||||||
|
|
||||||
|
typedef typename internal::ref_selector<XprType>::non_const_type MatrixTypeNested;
|
||||||
|
typedef typename internal::remove_all<XprType>::type NestedExpression;
|
||||||
|
|
||||||
|
class InnerIterator;
|
||||||
|
|
||||||
|
/** Fixed-size constructor
|
||||||
|
*/
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
inline ReshapedImpl_dense(XprType& xpr)
|
||||||
|
: m_xpr(xpr), m_rows(Rows), m_cols(Cols)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/** Dynamic-size constructor
|
||||||
|
*/
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
inline ReshapedImpl_dense(XprType& xpr, Index nRows, Index nCols)
|
||||||
|
: m_xpr(xpr), m_rows(nRows), m_cols(nCols)
|
||||||
|
{}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC Index rows() const { return m_rows; }
|
||||||
|
EIGEN_DEVICE_FUNC Index cols() const { return m_cols; }
|
||||||
|
|
||||||
|
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
/** \sa MapBase::data() */
|
||||||
|
EIGEN_DEVICE_FUNC inline const Scalar* data() const;
|
||||||
|
EIGEN_DEVICE_FUNC inline Index innerStride() const;
|
||||||
|
EIGEN_DEVICE_FUNC inline Index outerStride() const;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** \returns the nested expression */
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
const typename internal::remove_all<XprType>::type&
|
||||||
|
nestedExpression() const { return m_xpr; }
|
||||||
|
|
||||||
|
/** \returns the nested expression */
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
typename internal::remove_reference<XprType>::type&
|
||||||
|
nestedExpression() { return m_xpr; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
MatrixTypeNested m_xpr;
|
||||||
|
const internal::variable_if_dynamic<Index, Rows> m_rows;
|
||||||
|
const internal::variable_if_dynamic<Index, Cols> m_cols;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** \internal Internal implementation of dense Reshaped in the direct access case. */
|
||||||
|
template<typename XprType, int Rows, int Cols, int Order>
|
||||||
|
class ReshapedImpl_dense<XprType, Rows, Cols, Order, true>
|
||||||
|
: public MapBase<Reshaped<XprType, Rows, Cols, Order> >
|
||||||
|
{
|
||||||
|
typedef Reshaped<XprType, Rows, Cols, Order> ReshapedType;
|
||||||
|
typedef typename internal::ref_selector<XprType>::non_const_type XprTypeNested;
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef MapBase<ReshapedType> Base;
|
||||||
|
EIGEN_DENSE_PUBLIC_INTERFACE(ReshapedType)
|
||||||
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ReshapedImpl_dense)
|
||||||
|
|
||||||
|
/** Fixed-size constructor
|
||||||
|
*/
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
inline ReshapedImpl_dense(XprType& xpr)
|
||||||
|
: Base(xpr.data()), m_xpr(xpr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/** Dynamic-size constructor
|
||||||
|
*/
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
inline ReshapedImpl_dense(XprType& xpr, Index nRows, Index nCols)
|
||||||
|
: Base(xpr.data(), nRows, nCols),
|
||||||
|
m_xpr(xpr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
const typename internal::remove_all<XprTypeNested>::type& nestedExpression() const
|
||||||
|
{
|
||||||
|
return m_xpr;
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
XprType& nestedExpression() { return m_xpr; }
|
||||||
|
|
||||||
|
/** \sa MapBase::innerStride() */
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
|
inline Index innerStride() const
|
||||||
|
{
|
||||||
|
return m_xpr.innerStride();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \sa MapBase::outerStride() */
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
|
inline Index outerStride() const
|
||||||
|
{
|
||||||
|
return ((Flags&RowMajorBit)==RowMajorBit) ? this->cols() : this->rows();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
XprTypeNested m_xpr;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Evaluators
|
||||||
|
template<typename ArgType, int Rows, int Cols, int Order, bool HasDirectAccess> struct reshaped_evaluator;
|
||||||
|
|
||||||
|
template<typename ArgType, int Rows, int Cols, int Order>
|
||||||
|
struct evaluator<Reshaped<ArgType, Rows, Cols, Order> >
|
||||||
|
: reshaped_evaluator<ArgType, Rows, Cols, Order, traits<Reshaped<ArgType,Rows,Cols,Order> >::HasDirectAccess>
|
||||||
|
{
|
||||||
|
typedef Reshaped<ArgType, Rows, Cols, Order> XprType;
|
||||||
|
typedef typename XprType::Scalar Scalar;
|
||||||
|
// TODO: should check for smaller packet types
|
||||||
|
typedef typename packet_traits<Scalar>::type PacketScalar;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
|
||||||
|
HasDirectAccess = traits<XprType>::HasDirectAccess,
|
||||||
|
|
||||||
|
// RowsAtCompileTime = traits<XprType>::RowsAtCompileTime,
|
||||||
|
// ColsAtCompileTime = traits<XprType>::ColsAtCompileTime,
|
||||||
|
// MaxRowsAtCompileTime = traits<XprType>::MaxRowsAtCompileTime,
|
||||||
|
// MaxColsAtCompileTime = traits<XprType>::MaxColsAtCompileTime,
|
||||||
|
//
|
||||||
|
// InnerStrideAtCompileTime = traits<XprType>::HasSameStorageOrderAsXprType
|
||||||
|
// ? int(inner_stride_at_compile_time<ArgType>::ret)
|
||||||
|
// : Dynamic,
|
||||||
|
// OuterStrideAtCompileTime = Dynamic,
|
||||||
|
|
||||||
|
FlagsLinearAccessBit = (traits<XprType>::RowsAtCompileTime == 1 || traits<XprType>::ColsAtCompileTime == 1 || HasDirectAccess) ? LinearAccessBit : 0,
|
||||||
|
FlagsRowMajorBit = (traits<XprType>::ReshapedStorageOrder==int(RowMajor)) ? RowMajorBit : 0,
|
||||||
|
FlagsDirectAccessBit = HasDirectAccess ? DirectAccessBit : 0,
|
||||||
|
Flags0 = evaluator<ArgType>::Flags & (HereditaryBits & ~RowMajorBit),
|
||||||
|
Flags = Flags0 | FlagsLinearAccessBit | FlagsRowMajorBit | FlagsDirectAccessBit,
|
||||||
|
|
||||||
|
PacketAlignment = unpacket_traits<PacketScalar>::alignment,
|
||||||
|
Alignment = evaluator<ArgType>::Alignment
|
||||||
|
};
|
||||||
|
typedef reshaped_evaluator<ArgType, Rows, Cols, Order, HasDirectAccess> reshaped_evaluator_type;
|
||||||
|
EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr) : reshaped_evaluator_type(xpr)
|
||||||
|
{
|
||||||
|
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ArgType, int Rows, int Cols, int Order>
|
||||||
|
struct reshaped_evaluator<ArgType, Rows, Cols, Order, /* HasDirectAccess */ false>
|
||||||
|
: evaluator_base<Reshaped<ArgType, Rows, Cols, Order> >
|
||||||
|
{
|
||||||
|
typedef Reshaped<ArgType, Rows, Cols, Order> XprType;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CoeffReadCost = evaluator<ArgType>::CoeffReadCost /* TODO + cost of index computations */,
|
||||||
|
|
||||||
|
Flags = (evaluator<ArgType>::Flags & (HereditaryBits /*| LinearAccessBit | DirectAccessBit*/)),
|
||||||
|
|
||||||
|
Alignment = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC explicit reshaped_evaluator(const XprType& xpr) : m_argImpl(xpr.nestedExpression()), m_xpr(xpr)
|
||||||
|
{
|
||||||
|
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef typename XprType::Scalar Scalar;
|
||||||
|
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
||||||
|
|
||||||
|
typedef std::pair<Index, Index> RowCol;
|
||||||
|
|
||||||
|
inline RowCol index_remap(Index rowId, Index colId) const
|
||||||
|
{
|
||||||
|
if(Order==ColMajor)
|
||||||
|
{
|
||||||
|
const Index nth_elem_idx = colId * m_xpr.rows() + rowId;
|
||||||
|
return RowCol(nth_elem_idx % m_xpr.nestedExpression().rows(),
|
||||||
|
nth_elem_idx / m_xpr.nestedExpression().rows());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const Index nth_elem_idx = colId + rowId * m_xpr.cols();
|
||||||
|
return RowCol(nth_elem_idx / m_xpr.nestedExpression().cols(),
|
||||||
|
nth_elem_idx % m_xpr.nestedExpression().cols());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
inline Scalar& coeffRef(Index rowId, Index colId)
|
||||||
|
{
|
||||||
|
EIGEN_STATIC_ASSERT_LVALUE(XprType)
|
||||||
|
const RowCol row_col = index_remap(rowId, colId);
|
||||||
|
return m_argImpl.coeffRef(row_col.first, row_col.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
inline const Scalar& coeffRef(Index rowId, Index colId) const
|
||||||
|
{
|
||||||
|
const RowCol row_col = index_remap(rowId, colId);
|
||||||
|
return m_argImpl.coeffRef(row_col.first, row_col.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index rowId, Index colId) const
|
||||||
|
{
|
||||||
|
const RowCol row_col = index_remap(rowId, colId);
|
||||||
|
return m_argImpl.coeff(row_col.first, row_col.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
inline Scalar& coeffRef(Index index)
|
||||||
|
{
|
||||||
|
EIGEN_STATIC_ASSERT_LVALUE(XprType)
|
||||||
|
const RowCol row_col = index_remap(Rows == 1 ? 0 : index,
|
||||||
|
Rows == 1 ? index : 0);
|
||||||
|
return m_argImpl.coeffRef(row_col.first, row_col.second);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
inline const Scalar& coeffRef(Index index) const
|
||||||
|
{
|
||||||
|
const RowCol row_col = index_remap(Rows == 1 ? 0 : index,
|
||||||
|
Rows == 1 ? index : 0);
|
||||||
|
return m_argImpl.coeffRef(row_col.first, row_col.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
inline const CoeffReturnType coeff(Index index) const
|
||||||
|
{
|
||||||
|
const RowCol row_col = index_remap(Rows == 1 ? 0 : index,
|
||||||
|
Rows == 1 ? index : 0);
|
||||||
|
return m_argImpl.coeff(row_col.first, row_col.second);
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
template<int LoadMode>
|
||||||
|
inline PacketScalar packet(Index rowId, Index colId) const
|
||||||
|
{
|
||||||
|
const RowCol row_col = index_remap(rowId, colId);
|
||||||
|
return m_argImpl.template packet<Unaligned>(row_col.first, row_col.second);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
inline void writePacket(Index rowId, Index colId, const PacketScalar& val)
|
||||||
|
{
|
||||||
|
const RowCol row_col = index_remap(rowId, colId);
|
||||||
|
m_argImpl.const_cast_derived().template writePacket<Unaligned>
|
||||||
|
(row_col.first, row_col.second, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
inline PacketScalar packet(Index index) const
|
||||||
|
{
|
||||||
|
const RowCol row_col = index_remap(RowsAtCompileTime == 1 ? 0 : index,
|
||||||
|
RowsAtCompileTime == 1 ? index : 0);
|
||||||
|
return m_argImpl.template packet<Unaligned>(row_col.first, row_col.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
inline void writePacket(Index index, const PacketScalar& val)
|
||||||
|
{
|
||||||
|
const RowCol row_col = index_remap(RowsAtCompileTime == 1 ? 0 : index,
|
||||||
|
RowsAtCompileTime == 1 ? index : 0);
|
||||||
|
return m_argImpl.template packet<Unaligned>(row_col.first, row_col.second, val);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
protected:
|
||||||
|
|
||||||
|
evaluator<ArgType> m_argImpl;
|
||||||
|
const XprType& m_xpr;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ArgType, int Rows, int Cols, int Order>
|
||||||
|
struct reshaped_evaluator<ArgType, Rows, Cols, Order, /* HasDirectAccess */ true>
|
||||||
|
: mapbase_evaluator<Reshaped<ArgType, Rows, Cols, Order>,
|
||||||
|
typename Reshaped<ArgType, Rows, Cols, Order>::PlainObject>
|
||||||
|
{
|
||||||
|
typedef Reshaped<ArgType, Rows, Cols, Order> XprType;
|
||||||
|
typedef typename XprType::Scalar Scalar;
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC explicit reshaped_evaluator(const XprType& xpr)
|
||||||
|
: mapbase_evaluator<XprType, typename XprType::PlainObject>(xpr)
|
||||||
|
{
|
||||||
|
// TODO: for the 3.4 release, this should be turned to an internal assertion, but let's keep it as is for the beta lifetime
|
||||||
|
eigen_assert(((internal::UIntPtr(xpr.data()) % EIGEN_PLAIN_ENUM_MAX(1,evaluator<XprType>::Alignment)) == 0) && "data is not aligned");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace internal
|
||||||
|
|
||||||
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
#endif // EIGEN_RESHAPED_H
|
||||||
|
|
@ -60,8 +60,10 @@ template<typename Derived> class ReturnByValue
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline void evalTo(Dest& dst) const
|
inline void evalTo(Dest& dst) const
|
||||||
{ static_cast<const Derived*>(this)->evalTo(dst); }
|
{ static_cast<const Derived*>(this)->evalTo(dst); }
|
||||||
EIGEN_DEVICE_FUNC inline Index rows() const { return static_cast<const Derived*>(this)->rows(); }
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
EIGEN_DEVICE_FUNC inline Index cols() const { return static_cast<const Derived*>(this)->cols(); }
|
inline Index rows() const EIGEN_NOEXCEPT { return static_cast<const Derived*>(this)->rows(); }
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
|
inline Index cols() const EIGEN_NOEXCEPT { return static_cast<const Derived*>(this)->cols(); }
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
#define Unusable YOU_ARE_TRYING_TO_ACCESS_A_SINGLE_COEFFICIENT_IN_A_SPECIAL_EXPRESSION_WHERE_THAT_IS_NOT_ALLOWED_BECAUSE_THAT_WOULD_BE_INEFFICIENT
|
#define Unusable YOU_ARE_TRYING_TO_ACCESS_A_SINGLE_COEFFICIENT_IN_A_SPECIAL_EXPRESSION_WHERE_THAT_IS_NOT_ALLOWED_BECAUSE_THAT_WOULD_BE_INEFFICIENT
|
||||||
|
|
@ -79,7 +81,7 @@ template<typename Derived> class ReturnByValue
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
Derived& DenseBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
|
EIGEN_DEVICE_FUNC Derived& DenseBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
|
||||||
{
|
{
|
||||||
other.evalTo(derived());
|
other.evalTo(derived());
|
||||||
return derived();
|
return derived();
|
||||||
|
|
|
||||||
|
|
@ -89,8 +89,10 @@ template<typename MatrixType, int Direction> class Reverse
|
||||||
|
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reverse)
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reverse)
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline Index rows() const { return m_matrix.rows(); }
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
EIGEN_DEVICE_FUNC inline Index cols() const { return m_matrix.cols(); }
|
inline Index rows() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
|
inline Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline Index innerStride() const
|
EIGEN_DEVICE_FUNC inline Index innerStride() const
|
||||||
{
|
{
|
||||||
|
|
@ -114,7 +116,7 @@ template<typename MatrixType, int Direction> class Reverse
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline typename DenseBase<Derived>::ReverseReturnType
|
EIGEN_DEVICE_FUNC inline typename DenseBase<Derived>::ReverseReturnType
|
||||||
DenseBase<Derived>::reverse()
|
DenseBase<Derived>::reverse()
|
||||||
{
|
{
|
||||||
return ReverseReturnType(derived());
|
return ReverseReturnType(derived());
|
||||||
|
|
@ -136,7 +138,7 @@ DenseBase<Derived>::reverse()
|
||||||
*
|
*
|
||||||
* \sa VectorwiseOp::reverseInPlace(), reverse() */
|
* \sa VectorwiseOp::reverseInPlace(), reverse() */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline void DenseBase<Derived>::reverseInPlace()
|
EIGEN_DEVICE_FUNC inline void DenseBase<Derived>::reverseInPlace()
|
||||||
{
|
{
|
||||||
if(cols()>rows())
|
if(cols()>rows())
|
||||||
{
|
{
|
||||||
|
|
@ -171,8 +173,10 @@ struct vectorwise_reverse_inplace_impl<Vertical>
|
||||||
template<typename ExpressionType>
|
template<typename ExpressionType>
|
||||||
static void run(ExpressionType &xpr)
|
static void run(ExpressionType &xpr)
|
||||||
{
|
{
|
||||||
|
const int HalfAtCompileTime = ExpressionType::RowsAtCompileTime==Dynamic?Dynamic:ExpressionType::RowsAtCompileTime/2;
|
||||||
Index half = xpr.rows()/2;
|
Index half = xpr.rows()/2;
|
||||||
xpr.topRows(half).swap(xpr.bottomRows(half).colwise().reverse());
|
xpr.topRows(fix<HalfAtCompileTime>(half))
|
||||||
|
.swap(xpr.bottomRows(fix<HalfAtCompileTime>(half)).colwise().reverse());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -182,8 +186,10 @@ struct vectorwise_reverse_inplace_impl<Horizontal>
|
||||||
template<typename ExpressionType>
|
template<typename ExpressionType>
|
||||||
static void run(ExpressionType &xpr)
|
static void run(ExpressionType &xpr)
|
||||||
{
|
{
|
||||||
|
const int HalfAtCompileTime = ExpressionType::ColsAtCompileTime==Dynamic?Dynamic:ExpressionType::ColsAtCompileTime/2;
|
||||||
Index half = xpr.cols()/2;
|
Index half = xpr.cols()/2;
|
||||||
xpr.leftCols(half).swap(xpr.rightCols(half).rowwise().reverse());
|
xpr.leftCols(fix<HalfAtCompileTime>(half))
|
||||||
|
.swap(xpr.rightCols(fix<HalfAtCompileTime>(half)).rowwise().reverse());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -201,9 +207,9 @@ struct vectorwise_reverse_inplace_impl<Horizontal>
|
||||||
*
|
*
|
||||||
* \sa DenseBase::reverseInPlace(), reverse() */
|
* \sa DenseBase::reverseInPlace(), reverse() */
|
||||||
template<typename ExpressionType, int Direction>
|
template<typename ExpressionType, int Direction>
|
||||||
void VectorwiseOp<ExpressionType,Direction>::reverseInPlace()
|
EIGEN_DEVICE_FUNC void VectorwiseOp<ExpressionType,Direction>::reverseInPlace()
|
||||||
{
|
{
|
||||||
internal::vectorwise_reverse_inplace_impl<Direction>::run(_expression().const_cast_derived());
|
internal::vectorwise_reverse_inplace_impl<Direction>::run(m_matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
|
||||||
|
|
@ -67,8 +67,10 @@ class Select : public internal::dense_xpr_base< Select<ConditionMatrixType, Then
|
||||||
eigen_assert(m_condition.cols() == m_then.cols() && m_condition.cols() == m_else.cols());
|
eigen_assert(m_condition.cols() == m_then.cols() && m_condition.cols() == m_else.cols());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline EIGEN_DEVICE_FUNC Index rows() const { return m_condition.rows(); }
|
inline EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline EIGEN_DEVICE_FUNC Index cols() const { return m_condition.cols(); }
|
Index rows() const EIGEN_NOEXCEPT { return m_condition.rows(); }
|
||||||
|
inline EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
|
Index cols() const EIGEN_NOEXCEPT { return m_condition.cols(); }
|
||||||
|
|
||||||
inline EIGEN_DEVICE_FUNC
|
inline EIGEN_DEVICE_FUNC
|
||||||
const Scalar coeff(Index i, Index j) const
|
const Scalar coeff(Index i, Index j) const
|
||||||
|
|
@ -120,7 +122,7 @@ class Select : public internal::dense_xpr_base< Select<ConditionMatrixType, Then
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename ThenDerived,typename ElseDerived>
|
template<typename ThenDerived,typename ElseDerived>
|
||||||
inline const Select<Derived,ThenDerived,ElseDerived>
|
inline EIGEN_DEVICE_FUNC const Select<Derived,ThenDerived,ElseDerived>
|
||||||
DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
|
DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
|
||||||
const DenseBase<ElseDerived>& elseMatrix) const
|
const DenseBase<ElseDerived>& elseMatrix) const
|
||||||
{
|
{
|
||||||
|
|
@ -134,7 +136,7 @@ DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename ThenDerived>
|
template<typename ThenDerived>
|
||||||
inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
|
inline EIGEN_DEVICE_FUNC const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
|
||||||
DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
|
DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
|
||||||
const typename ThenDerived::Scalar& elseScalar) const
|
const typename ThenDerived::Scalar& elseScalar) const
|
||||||
{
|
{
|
||||||
|
|
@ -149,7 +151,7 @@ DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename ElseDerived>
|
template<typename ElseDerived>
|
||||||
inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
|
inline EIGEN_DEVICE_FUNC const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
|
||||||
DenseBase<Derived>::select(const typename ElseDerived::Scalar& thenScalar,
|
DenseBase<Derived>::select(const typename ElseDerived::Scalar& thenScalar,
|
||||||
const DenseBase<ElseDerived>& elseMatrix) const
|
const DenseBase<ElseDerived>& elseMatrix) const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -61,11 +61,12 @@ template<typename _MatrixType, unsigned int UpLo> class SelfAdjointView
|
||||||
typedef typename internal::traits<SelfAdjointView>::Scalar Scalar;
|
typedef typename internal::traits<SelfAdjointView>::Scalar Scalar;
|
||||||
typedef typename MatrixType::StorageIndex StorageIndex;
|
typedef typename MatrixType::StorageIndex StorageIndex;
|
||||||
typedef typename internal::remove_all<typename MatrixType::ConjugateReturnType>::type MatrixConjugateReturnType;
|
typedef typename internal::remove_all<typename MatrixType::ConjugateReturnType>::type MatrixConjugateReturnType;
|
||||||
|
typedef SelfAdjointView<typename internal::add_const<MatrixType>::type, UpLo> ConstSelfAdjointView;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
Mode = internal::traits<SelfAdjointView>::Mode,
|
Mode = internal::traits<SelfAdjointView>::Mode,
|
||||||
Flags = internal::traits<SelfAdjointView>::Flags,
|
Flags = internal::traits<SelfAdjointView>::Flags,
|
||||||
TransposeMode = ((Mode & Upper) ? Lower : 0) | ((Mode & Lower) ? Upper : 0)
|
TransposeMode = ((int(Mode) & int(Upper)) ? Lower : 0) | ((int(Mode) & int(Lower)) ? Upper : 0)
|
||||||
};
|
};
|
||||||
typedef typename MatrixType::PlainObject PlainObject;
|
typedef typename MatrixType::PlainObject PlainObject;
|
||||||
|
|
||||||
|
|
@ -75,14 +76,14 @@ template<typename _MatrixType, unsigned int UpLo> class SelfAdjointView
|
||||||
EIGEN_STATIC_ASSERT(UpLo==Lower || UpLo==Upper,SELFADJOINTVIEW_ACCEPTS_UPPER_AND_LOWER_MODE_ONLY);
|
EIGEN_STATIC_ASSERT(UpLo==Lower || UpLo==Upper,SELFADJOINTVIEW_ACCEPTS_UPPER_AND_LOWER_MODE_ONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index rows() const { return m_matrix.rows(); }
|
inline Index rows() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index cols() const { return m_matrix.cols(); }
|
inline Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index outerStride() const { return m_matrix.outerStride(); }
|
inline Index outerStride() const EIGEN_NOEXCEPT { return m_matrix.outerStride(); }
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index innerStride() const { return m_matrix.innerStride(); }
|
inline Index innerStride() const EIGEN_NOEXCEPT { return m_matrix.innerStride(); }
|
||||||
|
|
||||||
/** \sa MatrixBase::coeff()
|
/** \sa MatrixBase::coeff()
|
||||||
* \warning the coordinates must fit into the referenced triangular part
|
* \warning the coordinates must fit into the referenced triangular part
|
||||||
|
|
@ -197,6 +198,18 @@ template<typename _MatrixType, unsigned int UpLo> class SelfAdjointView
|
||||||
inline const ConjugateReturnType conjugate() const
|
inline const ConjugateReturnType conjugate() const
|
||||||
{ return ConjugateReturnType(m_matrix.conjugate()); }
|
{ return ConjugateReturnType(m_matrix.conjugate()); }
|
||||||
|
|
||||||
|
/** \returns an expression of the complex conjugate of \c *this if Cond==true,
|
||||||
|
* returns \c *this otherwise.
|
||||||
|
*/
|
||||||
|
template<bool Cond>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
inline typename internal::conditional<Cond,ConjugateReturnType,ConstSelfAdjointView>::type
|
||||||
|
conjugateIf() const
|
||||||
|
{
|
||||||
|
typedef typename internal::conditional<Cond,ConjugateReturnType,ConstSelfAdjointView>::type ReturnType;
|
||||||
|
return ReturnType(m_matrix.template conjugateIf<Cond>());
|
||||||
|
}
|
||||||
|
|
||||||
typedef SelfAdjointView<const typename MatrixType::AdjointReturnType,TransposeMode> AdjointReturnType;
|
typedef SelfAdjointView<const typename MatrixType::AdjointReturnType,TransposeMode> AdjointReturnType;
|
||||||
/** \sa MatrixBase::adjoint() const */
|
/** \sa MatrixBase::adjoint() const */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
|
|
@ -324,7 +337,7 @@ public:
|
||||||
/** This is the const version of MatrixBase::selfadjointView() */
|
/** This is the const version of MatrixBase::selfadjointView() */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<unsigned int UpLo>
|
template<unsigned int UpLo>
|
||||||
typename MatrixBase<Derived>::template ConstSelfAdjointViewReturnType<UpLo>::Type
|
EIGEN_DEVICE_FUNC typename MatrixBase<Derived>::template ConstSelfAdjointViewReturnType<UpLo>::Type
|
||||||
MatrixBase<Derived>::selfadjointView() const
|
MatrixBase<Derived>::selfadjointView() const
|
||||||
{
|
{
|
||||||
return typename ConstSelfAdjointViewReturnType<UpLo>::Type(derived());
|
return typename ConstSelfAdjointViewReturnType<UpLo>::Type(derived());
|
||||||
|
|
@ -341,7 +354,7 @@ MatrixBase<Derived>::selfadjointView() const
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<unsigned int UpLo>
|
template<unsigned int UpLo>
|
||||||
typename MatrixBase<Derived>::template SelfAdjointViewReturnType<UpLo>::Type
|
EIGEN_DEVICE_FUNC typename MatrixBase<Derived>::template SelfAdjointViewReturnType<UpLo>::Type
|
||||||
MatrixBase<Derived>::selfadjointView()
|
MatrixBase<Derived>::selfadjointView()
|
||||||
{
|
{
|
||||||
return typename SelfAdjointViewReturnType<UpLo>::Type(derived());
|
return typename SelfAdjointViewReturnType<UpLo>::Type(derived());
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ template<typename Decomposition, typename RhsType, typename StorageKind> class S
|
||||||
*
|
*
|
||||||
* \brief Pseudo expression representing a solving operation
|
* \brief Pseudo expression representing a solving operation
|
||||||
*
|
*
|
||||||
* \tparam Decomposition the type of the matrix or decomposion object
|
* \tparam Decomposition the type of the matrix or decomposition object
|
||||||
* \tparam Rhstype the type of the right-hand side
|
* \tparam Rhstype the type of the right-hand side
|
||||||
*
|
*
|
||||||
* This class represents an expression of A.solve(B)
|
* This class represents an expression of A.solve(B)
|
||||||
|
|
@ -69,8 +69,8 @@ public:
|
||||||
: m_dec(dec), m_rhs(rhs)
|
: m_dec(dec), m_rhs(rhs)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC Index rows() const { return m_dec.cols(); }
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_dec.cols(); }
|
||||||
EIGEN_DEVICE_FUNC Index cols() const { return m_rhs.cols(); }
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_rhs.cols(); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC const Decomposition& dec() const { return m_dec; }
|
EIGEN_DEVICE_FUNC const Decomposition& dec() const { return m_dec; }
|
||||||
EIGEN_DEVICE_FUNC const RhsType& rhs() const { return m_rhs; }
|
EIGEN_DEVICE_FUNC const RhsType& rhs() const { return m_rhs; }
|
||||||
|
|
@ -181,7 +181,7 @@ struct Assignment<DstXprType, Solve<CwiseUnaryOp<internal::scalar_conjugate_op<t
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namepsace internal
|
} // end namespace internal
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ namespace internal {
|
||||||
template<typename LhsScalar, typename RhsScalar, typename Index, int Side, int Mode, bool Conjugate, int StorageOrder>
|
template<typename LhsScalar, typename RhsScalar, typename Index, int Side, int Mode, bool Conjugate, int StorageOrder>
|
||||||
struct triangular_solve_vector;
|
struct triangular_solve_vector;
|
||||||
|
|
||||||
template <typename Scalar, typename Index, int Side, int Mode, bool Conjugate, int TriStorageOrder, int OtherStorageOrder>
|
template <typename Scalar, typename Index, int Side, int Mode, bool Conjugate, int TriStorageOrder, int OtherStorageOrder, int OtherInnerStride>
|
||||||
struct triangular_solve_matrix;
|
struct triangular_solve_matrix;
|
||||||
|
|
||||||
// small helper struct extracting some traits on the underlying solver operation
|
// small helper struct extracting some traits on the underlying solver operation
|
||||||
|
|
@ -54,7 +54,7 @@ struct triangular_solver_selector<Lhs,Rhs,Side,Mode,NoUnrolling,1>
|
||||||
typedef blas_traits<Lhs> LhsProductTraits;
|
typedef blas_traits<Lhs> LhsProductTraits;
|
||||||
typedef typename LhsProductTraits::ExtractType ActualLhsType;
|
typedef typename LhsProductTraits::ExtractType ActualLhsType;
|
||||||
typedef Map<Matrix<RhsScalar,Dynamic,1>, Aligned> MappedRhs;
|
typedef Map<Matrix<RhsScalar,Dynamic,1>, Aligned> MappedRhs;
|
||||||
static void run(const Lhs& lhs, Rhs& rhs)
|
static EIGEN_DEVICE_FUNC void run(const Lhs& lhs, Rhs& rhs)
|
||||||
{
|
{
|
||||||
ActualLhsType actualLhs = LhsProductTraits::extract(lhs);
|
ActualLhsType actualLhs = LhsProductTraits::extract(lhs);
|
||||||
|
|
||||||
|
|
@ -85,7 +85,7 @@ struct triangular_solver_selector<Lhs,Rhs,Side,Mode,NoUnrolling,Dynamic>
|
||||||
typedef blas_traits<Lhs> LhsProductTraits;
|
typedef blas_traits<Lhs> LhsProductTraits;
|
||||||
typedef typename LhsProductTraits::DirectLinearAccessType ActualLhsType;
|
typedef typename LhsProductTraits::DirectLinearAccessType ActualLhsType;
|
||||||
|
|
||||||
static void run(const Lhs& lhs, Rhs& rhs)
|
static EIGEN_DEVICE_FUNC void run(const Lhs& lhs, Rhs& rhs)
|
||||||
{
|
{
|
||||||
typename internal::add_const_on_value_type<ActualLhsType>::type actualLhs = LhsProductTraits::extract(lhs);
|
typename internal::add_const_on_value_type<ActualLhsType>::type actualLhs = LhsProductTraits::extract(lhs);
|
||||||
|
|
||||||
|
|
@ -98,8 +98,8 @@ struct triangular_solver_selector<Lhs,Rhs,Side,Mode,NoUnrolling,Dynamic>
|
||||||
BlockingType blocking(rhs.rows(), rhs.cols(), size, 1, false);
|
BlockingType blocking(rhs.rows(), rhs.cols(), size, 1, false);
|
||||||
|
|
||||||
triangular_solve_matrix<Scalar,Index,Side,Mode,LhsProductTraits::NeedToConjugate,(int(Lhs::Flags) & RowMajorBit) ? RowMajor : ColMajor,
|
triangular_solve_matrix<Scalar,Index,Side,Mode,LhsProductTraits::NeedToConjugate,(int(Lhs::Flags) & RowMajorBit) ? RowMajor : ColMajor,
|
||||||
(Rhs::Flags&RowMajorBit) ? RowMajor : ColMajor>
|
(Rhs::Flags&RowMajorBit) ? RowMajor : ColMajor, Rhs::InnerStrideAtCompileTime>
|
||||||
::run(size, othersize, &actualLhs.coeffRef(0,0), actualLhs.outerStride(), &rhs.coeffRef(0,0), rhs.outerStride(), blocking);
|
::run(size, othersize, &actualLhs.coeffRef(0,0), actualLhs.outerStride(), &rhs.coeffRef(0,0), rhs.innerStride(), rhs.outerStride(), blocking);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -118,7 +118,7 @@ struct triangular_solver_unroller<Lhs,Rhs,Mode,LoopIndex,Size,false> {
|
||||||
DiagIndex = IsLower ? LoopIndex : Size - LoopIndex - 1,
|
DiagIndex = IsLower ? LoopIndex : Size - LoopIndex - 1,
|
||||||
StartIndex = IsLower ? 0 : DiagIndex+1
|
StartIndex = IsLower ? 0 : DiagIndex+1
|
||||||
};
|
};
|
||||||
static void run(const Lhs& lhs, Rhs& rhs)
|
static EIGEN_DEVICE_FUNC void run(const Lhs& lhs, Rhs& rhs)
|
||||||
{
|
{
|
||||||
if (LoopIndex>0)
|
if (LoopIndex>0)
|
||||||
rhs.coeffRef(DiagIndex) -= lhs.row(DiagIndex).template segment<LoopIndex>(StartIndex).transpose()
|
rhs.coeffRef(DiagIndex) -= lhs.row(DiagIndex).template segment<LoopIndex>(StartIndex).transpose()
|
||||||
|
|
@ -133,18 +133,18 @@ struct triangular_solver_unroller<Lhs,Rhs,Mode,LoopIndex,Size,false> {
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, int Mode, int LoopIndex, int Size>
|
template<typename Lhs, typename Rhs, int Mode, int LoopIndex, int Size>
|
||||||
struct triangular_solver_unroller<Lhs,Rhs,Mode,LoopIndex,Size,true> {
|
struct triangular_solver_unroller<Lhs,Rhs,Mode,LoopIndex,Size,true> {
|
||||||
static void run(const Lhs&, Rhs&) {}
|
static EIGEN_DEVICE_FUNC void run(const Lhs&, Rhs&) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, int Mode>
|
template<typename Lhs, typename Rhs, int Mode>
|
||||||
struct triangular_solver_selector<Lhs,Rhs,OnTheLeft,Mode,CompleteUnrolling,1> {
|
struct triangular_solver_selector<Lhs,Rhs,OnTheLeft,Mode,CompleteUnrolling,1> {
|
||||||
static void run(const Lhs& lhs, Rhs& rhs)
|
static EIGEN_DEVICE_FUNC void run(const Lhs& lhs, Rhs& rhs)
|
||||||
{ triangular_solver_unroller<Lhs,Rhs,Mode,0,Rhs::SizeAtCompileTime>::run(lhs,rhs); }
|
{ triangular_solver_unroller<Lhs,Rhs,Mode,0,Rhs::SizeAtCompileTime>::run(lhs,rhs); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, int Mode>
|
template<typename Lhs, typename Rhs, int Mode>
|
||||||
struct triangular_solver_selector<Lhs,Rhs,OnTheRight,Mode,CompleteUnrolling,1> {
|
struct triangular_solver_selector<Lhs,Rhs,OnTheRight,Mode,CompleteUnrolling,1> {
|
||||||
static void run(const Lhs& lhs, Rhs& rhs)
|
static EIGEN_DEVICE_FUNC void run(const Lhs& lhs, Rhs& rhs)
|
||||||
{
|
{
|
||||||
Transpose<const Lhs> trLhs(lhs);
|
Transpose<const Lhs> trLhs(lhs);
|
||||||
Transpose<Rhs> trRhs(rhs);
|
Transpose<Rhs> trRhs(rhs);
|
||||||
|
|
@ -164,11 +164,11 @@ struct triangular_solver_selector<Lhs,Rhs,OnTheRight,Mode,CompleteUnrolling,1> {
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
template<typename MatrixType, unsigned int Mode>
|
template<typename MatrixType, unsigned int Mode>
|
||||||
template<int Side, typename OtherDerived>
|
template<int Side, typename OtherDerived>
|
||||||
void TriangularViewImpl<MatrixType,Mode,Dense>::solveInPlace(const MatrixBase<OtherDerived>& _other) const
|
EIGEN_DEVICE_FUNC void TriangularViewImpl<MatrixType,Mode,Dense>::solveInPlace(const MatrixBase<OtherDerived>& _other) const
|
||||||
{
|
{
|
||||||
OtherDerived& other = _other.const_cast_derived();
|
OtherDerived& other = _other.const_cast_derived();
|
||||||
eigen_assert( derived().cols() == derived().rows() && ((Side==OnTheLeft && derived().cols() == other.rows()) || (Side==OnTheRight && derived().cols() == other.cols())) );
|
eigen_assert( derived().cols() == derived().rows() && ((Side==OnTheLeft && derived().cols() == other.rows()) || (Side==OnTheRight && derived().cols() == other.cols())) );
|
||||||
eigen_assert((!(Mode & ZeroDiag)) && bool(Mode & (Upper|Lower)));
|
eigen_assert((!(int(Mode) & int(ZeroDiag))) && bool(int(Mode) & (int(Upper) | int(Lower))));
|
||||||
// If solving for a 0x0 matrix, nothing to do, simply return.
|
// If solving for a 0x0 matrix, nothing to do, simply return.
|
||||||
if (derived().cols() == 0)
|
if (derived().cols() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
@ -213,8 +213,8 @@ template<int Side, typename TriangularType, typename Rhs> struct triangular_solv
|
||||||
: m_triangularMatrix(tri), m_rhs(rhs)
|
: m_triangularMatrix(tri), m_rhs(rhs)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
inline Index rows() const { return m_rhs.rows(); }
|
inline EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_rhs.rows(); }
|
||||||
inline Index cols() const { return m_rhs.cols(); }
|
inline EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_rhs.cols(); }
|
||||||
|
|
||||||
template<typename Dest> inline void evalTo(Dest& dst) const
|
template<typename Dest> inline void evalTo(Dest& dst) const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,35 @@ namespace Eigen {
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
struct solve_assertion {
|
||||||
|
template<bool Transpose_, typename Rhs>
|
||||||
|
static void run(const Derived& solver, const Rhs& b) { solver.template _check_solve_assertion<Transpose_>(b); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
struct solve_assertion<Transpose<Derived> >
|
||||||
|
{
|
||||||
|
typedef Transpose<Derived> type;
|
||||||
|
|
||||||
|
template<bool Transpose_, typename Rhs>
|
||||||
|
static void run(const type& transpose, const Rhs& b)
|
||||||
|
{
|
||||||
|
internal::solve_assertion<typename internal::remove_all<Derived>::type>::template run<true>(transpose.nestedExpression(), b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Scalar, typename Derived>
|
||||||
|
struct solve_assertion<CwiseUnaryOp<Eigen::internal::scalar_conjugate_op<Scalar>, const Transpose<Derived> > >
|
||||||
|
{
|
||||||
|
typedef CwiseUnaryOp<Eigen::internal::scalar_conjugate_op<Scalar>, const Transpose<Derived> > type;
|
||||||
|
|
||||||
|
template<bool Transpose_, typename Rhs>
|
||||||
|
static void run(const type& adjoint, const Rhs& b)
|
||||||
|
{
|
||||||
|
internal::solve_assertion<typename internal::remove_all<Transpose<Derived> >::type>::template run<true>(adjoint.nestedExpression(), b);
|
||||||
|
}
|
||||||
|
};
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
/** \class SolverBase
|
/** \class SolverBase
|
||||||
|
|
@ -35,7 +62,7 @@ namespace internal {
|
||||||
*
|
*
|
||||||
* \warning Currently, any other usage of transpose() and adjoint() are not supported and will produce compilation errors.
|
* \warning Currently, any other usage of transpose() and adjoint() are not supported and will produce compilation errors.
|
||||||
*
|
*
|
||||||
* \sa class PartialPivLU, class FullPivLU
|
* \sa class PartialPivLU, class FullPivLU, class HouseholderQR, class ColPivHouseholderQR, class FullPivHouseholderQR, class CompleteOrthogonalDecomposition, class LLT, class LDLT, class SVDBase
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
class SolverBase : public EigenBase<Derived>
|
class SolverBase : public EigenBase<Derived>
|
||||||
|
|
@ -46,6 +73,9 @@ class SolverBase : public EigenBase<Derived>
|
||||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||||
typedef Scalar CoeffReturnType;
|
typedef Scalar CoeffReturnType;
|
||||||
|
|
||||||
|
template<typename Derived_>
|
||||||
|
friend struct internal::solve_assertion;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
|
RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
|
||||||
ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
|
ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
|
||||||
|
|
@ -56,7 +86,8 @@ class SolverBase : public EigenBase<Derived>
|
||||||
MaxSizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::MaxRowsAtCompileTime,
|
MaxSizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::MaxRowsAtCompileTime,
|
||||||
internal::traits<Derived>::MaxColsAtCompileTime>::ret),
|
internal::traits<Derived>::MaxColsAtCompileTime>::ret),
|
||||||
IsVectorAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime == 1
|
IsVectorAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime == 1
|
||||||
|| internal::traits<Derived>::MaxColsAtCompileTime == 1
|
|| internal::traits<Derived>::MaxColsAtCompileTime == 1,
|
||||||
|
NumDimensions = int(MaxSizeAtCompileTime) == 1 ? 0 : bool(IsVectorAtCompileTime) ? 1 : 2
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Default constructor */
|
/** Default constructor */
|
||||||
|
|
@ -74,7 +105,7 @@ class SolverBase : public EigenBase<Derived>
|
||||||
inline const Solve<Derived, Rhs>
|
inline const Solve<Derived, Rhs>
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
solve(const MatrixBase<Rhs>& b) const
|
||||||
{
|
{
|
||||||
eigen_assert(derived().rows()==b.rows() && "solve(): invalid number of rows of the right hand side matrix b");
|
internal::solve_assertion<typename internal::remove_all<Derived>::type>::template run<false>(derived(), b);
|
||||||
return Solve<Derived, Rhs>(derived(), b.derived());
|
return Solve<Derived, Rhs>(derived(), b.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,6 +143,13 @@ class SolverBase : public EigenBase<Derived>
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
template<bool Transpose_, typename Rhs>
|
||||||
|
void _check_solve_assertion(const Rhs& b) const {
|
||||||
|
EIGEN_ONLY_USED_FOR_DEBUG(b);
|
||||||
|
eigen_assert(derived().m_isInitialized && "Solver is not initialized.");
|
||||||
|
eigen_assert((Transpose_?derived().cols():derived().rows())==b.rows() && "SolverBase::solve(): invalid number of rows of the right hand side matrix b");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,71 @@ inline void stable_norm_kernel(const ExpressionType& bl, Scalar& ssq, Scalar& sc
|
||||||
ssq += (bl*invScale).squaredNorm();
|
ssq += (bl*invScale).squaredNorm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename VectorType, typename RealScalar>
|
||||||
|
void stable_norm_impl_inner_step(const VectorType &vec, RealScalar& ssq, RealScalar& scale, RealScalar& invScale)
|
||||||
|
{
|
||||||
|
typedef typename VectorType::Scalar Scalar;
|
||||||
|
const Index blockSize = 4096;
|
||||||
|
|
||||||
|
typedef typename internal::nested_eval<VectorType,2>::type VectorTypeCopy;
|
||||||
|
typedef typename internal::remove_all<VectorTypeCopy>::type VectorTypeCopyClean;
|
||||||
|
const VectorTypeCopy copy(vec);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CanAlign = ( (int(VectorTypeCopyClean::Flags)&DirectAccessBit)
|
||||||
|
|| (int(internal::evaluator<VectorTypeCopyClean>::Alignment)>0) // FIXME Alignment)>0 might not be enough
|
||||||
|
) && (blockSize*sizeof(Scalar)*2<EIGEN_STACK_ALLOCATION_LIMIT)
|
||||||
|
&& (EIGEN_MAX_STATIC_ALIGN_BYTES>0) // if we cannot allocate on the stack, then let's not bother about this optimization
|
||||||
|
};
|
||||||
|
typedef typename internal::conditional<CanAlign, Ref<const Matrix<Scalar,Dynamic,1,0,blockSize,1>, internal::evaluator<VectorTypeCopyClean>::Alignment>,
|
||||||
|
typename VectorTypeCopyClean::ConstSegmentReturnType>::type SegmentWrapper;
|
||||||
|
Index n = vec.size();
|
||||||
|
|
||||||
|
Index bi = internal::first_default_aligned(copy);
|
||||||
|
if (bi>0)
|
||||||
|
internal::stable_norm_kernel(copy.head(bi), ssq, scale, invScale);
|
||||||
|
for (; bi<n; bi+=blockSize)
|
||||||
|
internal::stable_norm_kernel(SegmentWrapper(copy.segment(bi,numext::mini(blockSize, n - bi))), ssq, scale, invScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename VectorType>
|
||||||
|
typename VectorType::RealScalar
|
||||||
|
stable_norm_impl(const VectorType &vec, typename enable_if<VectorType::IsVectorAtCompileTime>::type* = 0 )
|
||||||
|
{
|
||||||
|
using std::sqrt;
|
||||||
|
using std::abs;
|
||||||
|
|
||||||
|
Index n = vec.size();
|
||||||
|
|
||||||
|
if(n==1)
|
||||||
|
return abs(vec.coeff(0));
|
||||||
|
|
||||||
|
typedef typename VectorType::RealScalar RealScalar;
|
||||||
|
RealScalar scale(0);
|
||||||
|
RealScalar invScale(1);
|
||||||
|
RealScalar ssq(0); // sum of squares
|
||||||
|
|
||||||
|
stable_norm_impl_inner_step(vec, ssq, scale, invScale);
|
||||||
|
|
||||||
|
return scale * sqrt(ssq);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename MatrixType>
|
||||||
|
typename MatrixType::RealScalar
|
||||||
|
stable_norm_impl(const MatrixType &mat, typename enable_if<!MatrixType::IsVectorAtCompileTime>::type* = 0 )
|
||||||
|
{
|
||||||
|
using std::sqrt;
|
||||||
|
|
||||||
|
typedef typename MatrixType::RealScalar RealScalar;
|
||||||
|
RealScalar scale(0);
|
||||||
|
RealScalar invScale(1);
|
||||||
|
RealScalar ssq(0); // sum of squares
|
||||||
|
|
||||||
|
for(Index j=0; j<mat.outerSize(); ++j)
|
||||||
|
stable_norm_impl_inner_step(mat.innerVector(j), ssq, scale, invScale);
|
||||||
|
return scale * sqrt(ssq);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline typename NumTraits<typename traits<Derived>::Scalar>::Real
|
inline typename NumTraits<typename traits<Derived>::Scalar>::Real
|
||||||
blueNorm_impl(const EigenBase<Derived>& _vec)
|
blueNorm_impl(const EigenBase<Derived>& _vec)
|
||||||
|
|
@ -58,13 +123,7 @@ blueNorm_impl(const EigenBase<Derived>& _vec)
|
||||||
using std::pow;
|
using std::pow;
|
||||||
using std::sqrt;
|
using std::sqrt;
|
||||||
using std::abs;
|
using std::abs;
|
||||||
const Derived& vec(_vec.derived());
|
|
||||||
static bool initialized = false;
|
|
||||||
static RealScalar b1, b2, s1m, s2m, rbig, relerr;
|
|
||||||
if(!initialized)
|
|
||||||
{
|
|
||||||
int ibeta, it, iemin, iemax, iexp;
|
|
||||||
RealScalar eps;
|
|
||||||
// This program calculates the machine-dependent constants
|
// This program calculates the machine-dependent constants
|
||||||
// bl, b2, slm, s2m, relerr overfl
|
// bl, b2, slm, s2m, relerr overfl
|
||||||
// from the "basic" machine-dependent numbers
|
// from the "basic" machine-dependent numbers
|
||||||
|
|
@ -73,38 +132,35 @@ blueNorm_impl(const EigenBase<Derived>& _vec)
|
||||||
// For portability, the PORT subprograms "ilmaeh" and "rlmach"
|
// For portability, the PORT subprograms "ilmaeh" and "rlmach"
|
||||||
// are used. For any specific computer, each of the assignment
|
// are used. For any specific computer, each of the assignment
|
||||||
// statements can be replaced
|
// statements can be replaced
|
||||||
ibeta = std::numeric_limits<RealScalar>::radix; // base for floating-point numbers
|
static const int ibeta = std::numeric_limits<RealScalar>::radix; // base for floating-point numbers
|
||||||
it = std::numeric_limits<RealScalar>::digits; // number of base-beta digits in mantissa
|
static const int it = NumTraits<RealScalar>::digits(); // number of base-beta digits in mantissa
|
||||||
iemin = std::numeric_limits<RealScalar>::min_exponent; // minimum exponent
|
static const int iemin = NumTraits<RealScalar>::min_exponent(); // minimum exponent
|
||||||
iemax = std::numeric_limits<RealScalar>::max_exponent; // maximum exponent
|
static const int iemax = NumTraits<RealScalar>::max_exponent(); // maximum exponent
|
||||||
rbig = (std::numeric_limits<RealScalar>::max)(); // largest floating-point number
|
static const RealScalar rbig = NumTraits<RealScalar>::highest(); // largest floating-point number
|
||||||
|
static const RealScalar b1 = RealScalar(pow(RealScalar(ibeta),RealScalar(-((1-iemin)/2)))); // lower boundary of midrange
|
||||||
|
static const RealScalar b2 = RealScalar(pow(RealScalar(ibeta),RealScalar((iemax + 1 - it)/2))); // upper boundary of midrange
|
||||||
|
static const RealScalar s1m = RealScalar(pow(RealScalar(ibeta),RealScalar((2-iemin)/2))); // scaling factor for lower range
|
||||||
|
static const RealScalar s2m = RealScalar(pow(RealScalar(ibeta),RealScalar(- ((iemax+it)/2)))); // scaling factor for upper range
|
||||||
|
static const RealScalar eps = RealScalar(pow(double(ibeta), 1-it));
|
||||||
|
static const RealScalar relerr = sqrt(eps); // tolerance for neglecting asml
|
||||||
|
|
||||||
iexp = -((1-iemin)/2);
|
const Derived& vec(_vec.derived());
|
||||||
b1 = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // lower boundary of midrange
|
|
||||||
iexp = (iemax + 1 - it)/2;
|
|
||||||
b2 = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // upper boundary of midrange
|
|
||||||
|
|
||||||
iexp = (2-iemin)/2;
|
|
||||||
s1m = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for lower range
|
|
||||||
iexp = - ((iemax+it)/2);
|
|
||||||
s2m = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for upper range
|
|
||||||
|
|
||||||
eps = RealScalar(pow(double(ibeta), 1-it));
|
|
||||||
relerr = sqrt(eps); // tolerance for neglecting asml
|
|
||||||
initialized = true;
|
|
||||||
}
|
|
||||||
Index n = vec.size();
|
Index n = vec.size();
|
||||||
RealScalar ab2 = b2 / RealScalar(n);
|
RealScalar ab2 = b2 / RealScalar(n);
|
||||||
RealScalar asml = RealScalar(0);
|
RealScalar asml = RealScalar(0);
|
||||||
RealScalar amed = RealScalar(0);
|
RealScalar amed = RealScalar(0);
|
||||||
RealScalar abig = RealScalar(0);
|
RealScalar abig = RealScalar(0);
|
||||||
for(typename Derived::InnerIterator it(vec, 0); it; ++it)
|
|
||||||
|
for(Index j=0; j<vec.outerSize(); ++j)
|
||||||
{
|
{
|
||||||
RealScalar ax = abs(it.value());
|
for(typename Derived::InnerIterator iter(vec, j); iter; ++iter)
|
||||||
|
{
|
||||||
|
RealScalar ax = abs(iter.value());
|
||||||
if(ax > ab2) abig += numext::abs2(ax*s2m);
|
if(ax > ab2) abig += numext::abs2(ax*s2m);
|
||||||
else if(ax < b1) asml += numext::abs2(ax*s1m);
|
else if(ax < b1) asml += numext::abs2(ax*s1m);
|
||||||
else amed += numext::abs2(ax);
|
else amed += numext::abs2(ax);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if(amed!=amed)
|
if(amed!=amed)
|
||||||
return amed; // we got a NaN
|
return amed; // we got a NaN
|
||||||
if(abig > RealScalar(0))
|
if(abig > RealScalar(0))
|
||||||
|
|
@ -156,36 +212,7 @@ template<typename Derived>
|
||||||
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
|
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
|
||||||
MatrixBase<Derived>::stableNorm() const
|
MatrixBase<Derived>::stableNorm() const
|
||||||
{
|
{
|
||||||
using std::sqrt;
|
return internal::stable_norm_impl(derived());
|
||||||
using std::abs;
|
|
||||||
const Index blockSize = 4096;
|
|
||||||
RealScalar scale(0);
|
|
||||||
RealScalar invScale(1);
|
|
||||||
RealScalar ssq(0); // sum of square
|
|
||||||
|
|
||||||
typedef typename internal::nested_eval<Derived,2>::type DerivedCopy;
|
|
||||||
typedef typename internal::remove_all<DerivedCopy>::type DerivedCopyClean;
|
|
||||||
const DerivedCopy copy(derived());
|
|
||||||
|
|
||||||
enum {
|
|
||||||
CanAlign = ( (int(DerivedCopyClean::Flags)&DirectAccessBit)
|
|
||||||
|| (int(internal::evaluator<DerivedCopyClean>::Alignment)>0) // FIXME Alignment)>0 might not be enough
|
|
||||||
) && (blockSize*sizeof(Scalar)*2<EIGEN_STACK_ALLOCATION_LIMIT)
|
|
||||||
&& (EIGEN_MAX_STATIC_ALIGN_BYTES>0) // if we cannot allocate on the stack, then let's not bother about this optimization
|
|
||||||
};
|
|
||||||
typedef typename internal::conditional<CanAlign, Ref<const Matrix<Scalar,Dynamic,1,0,blockSize,1>, internal::evaluator<DerivedCopyClean>::Alignment>,
|
|
||||||
typename DerivedCopyClean::ConstSegmentReturnType>::type SegmentWrapper;
|
|
||||||
Index n = size();
|
|
||||||
|
|
||||||
if(n==1)
|
|
||||||
return abs(this->coeff(0));
|
|
||||||
|
|
||||||
Index bi = internal::first_default_aligned(copy);
|
|
||||||
if (bi>0)
|
|
||||||
internal::stable_norm_kernel(copy.head(bi), ssq, scale, invScale);
|
|
||||||
for (; bi<n; bi+=blockSize)
|
|
||||||
internal::stable_norm_kernel(SegmentWrapper(copy.segment(bi,numext::mini(blockSize, n - bi))), ssq, scale, invScale);
|
|
||||||
return scale * sqrt(ssq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the \em l2 norm of \c *this using the Blue's algorithm.
|
/** \returns the \em l2 norm of \c *this using the Blue's algorithm.
|
||||||
|
|
@ -213,6 +240,9 @@ template<typename Derived>
|
||||||
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
|
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
|
||||||
MatrixBase<Derived>::hypotNorm() const
|
MatrixBase<Derived>::hypotNorm() const
|
||||||
{
|
{
|
||||||
|
if(size()==1)
|
||||||
|
return numext::abs(coeff(0,0));
|
||||||
|
else
|
||||||
return this->cwiseAbs().redux(internal::scalar_hypot_op<RealScalar>());
|
return this->cwiseAbs().redux(internal::scalar_hypot_op<RealScalar>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,463 @@
|
||||||
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
|
// for linear algebra.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2018 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the Mozilla
|
||||||
|
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||||
|
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
#ifndef EIGEN_STLITERATORS_H
|
||||||
|
#define EIGEN_STLITERATORS_H
|
||||||
|
|
||||||
|
namespace Eigen {
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template<typename IteratorType>
|
||||||
|
struct indexed_based_stl_iterator_traits;
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
class indexed_based_stl_iterator_base
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
typedef indexed_based_stl_iterator_traits<Derived> traits;
|
||||||
|
typedef typename traits::XprType XprType;
|
||||||
|
typedef indexed_based_stl_iterator_base<typename traits::non_const_iterator> non_const_iterator;
|
||||||
|
typedef indexed_based_stl_iterator_base<typename traits::const_iterator> const_iterator;
|
||||||
|
typedef typename internal::conditional<internal::is_const<XprType>::value,non_const_iterator,const_iterator>::type other_iterator;
|
||||||
|
// NOTE: in C++03 we cannot declare friend classes through typedefs because we need to write friend class:
|
||||||
|
friend class indexed_based_stl_iterator_base<typename traits::const_iterator>;
|
||||||
|
friend class indexed_based_stl_iterator_base<typename traits::non_const_iterator>;
|
||||||
|
public:
|
||||||
|
typedef Index difference_type;
|
||||||
|
typedef std::random_access_iterator_tag iterator_category;
|
||||||
|
|
||||||
|
indexed_based_stl_iterator_base() EIGEN_NO_THROW : mp_xpr(0), m_index(0) {}
|
||||||
|
indexed_based_stl_iterator_base(XprType& xpr, Index index) EIGEN_NO_THROW : mp_xpr(&xpr), m_index(index) {}
|
||||||
|
|
||||||
|
indexed_based_stl_iterator_base(const non_const_iterator& other) EIGEN_NO_THROW
|
||||||
|
: mp_xpr(other.mp_xpr), m_index(other.m_index)
|
||||||
|
{}
|
||||||
|
|
||||||
|
indexed_based_stl_iterator_base& operator=(const non_const_iterator& other)
|
||||||
|
{
|
||||||
|
mp_xpr = other.mp_xpr;
|
||||||
|
m_index = other.m_index;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Derived& operator++() { ++m_index; return derived(); }
|
||||||
|
Derived& operator--() { --m_index; return derived(); }
|
||||||
|
|
||||||
|
Derived operator++(int) { Derived prev(derived()); operator++(); return prev;}
|
||||||
|
Derived operator--(int) { Derived prev(derived()); operator--(); return prev;}
|
||||||
|
|
||||||
|
friend Derived operator+(const indexed_based_stl_iterator_base& a, Index b) { Derived ret(a.derived()); ret += b; return ret; }
|
||||||
|
friend Derived operator-(const indexed_based_stl_iterator_base& a, Index b) { Derived ret(a.derived()); ret -= b; return ret; }
|
||||||
|
friend Derived operator+(Index a, const indexed_based_stl_iterator_base& b) { Derived ret(b.derived()); ret += a; return ret; }
|
||||||
|
friend Derived operator-(Index a, const indexed_based_stl_iterator_base& b) { Derived ret(b.derived()); ret -= a; return ret; }
|
||||||
|
|
||||||
|
Derived& operator+=(Index b) { m_index += b; return derived(); }
|
||||||
|
Derived& operator-=(Index b) { m_index -= b; return derived(); }
|
||||||
|
|
||||||
|
difference_type operator-(const indexed_based_stl_iterator_base& other) const
|
||||||
|
{
|
||||||
|
eigen_assert(mp_xpr == other.mp_xpr);
|
||||||
|
return m_index - other.m_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
difference_type operator-(const other_iterator& other) const
|
||||||
|
{
|
||||||
|
eigen_assert(mp_xpr == other.mp_xpr);
|
||||||
|
return m_index - other.m_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index == other.m_index; }
|
||||||
|
bool operator!=(const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index != other.m_index; }
|
||||||
|
bool operator< (const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index < other.m_index; }
|
||||||
|
bool operator<=(const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index <= other.m_index; }
|
||||||
|
bool operator> (const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index > other.m_index; }
|
||||||
|
bool operator>=(const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index >= other.m_index; }
|
||||||
|
|
||||||
|
bool operator==(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index == other.m_index; }
|
||||||
|
bool operator!=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index != other.m_index; }
|
||||||
|
bool operator< (const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index < other.m_index; }
|
||||||
|
bool operator<=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index <= other.m_index; }
|
||||||
|
bool operator> (const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index > other.m_index; }
|
||||||
|
bool operator>=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index >= other.m_index; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
Derived& derived() { return static_cast<Derived&>(*this); }
|
||||||
|
const Derived& derived() const { return static_cast<const Derived&>(*this); }
|
||||||
|
|
||||||
|
XprType *mp_xpr;
|
||||||
|
Index m_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
class indexed_based_stl_reverse_iterator_base
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
typedef indexed_based_stl_iterator_traits<Derived> traits;
|
||||||
|
typedef typename traits::XprType XprType;
|
||||||
|
typedef indexed_based_stl_reverse_iterator_base<typename traits::non_const_iterator> non_const_iterator;
|
||||||
|
typedef indexed_based_stl_reverse_iterator_base<typename traits::const_iterator> const_iterator;
|
||||||
|
typedef typename internal::conditional<internal::is_const<XprType>::value,non_const_iterator,const_iterator>::type other_iterator;
|
||||||
|
// NOTE: in C++03 we cannot declare friend classes through typedefs because we need to write friend class:
|
||||||
|
friend class indexed_based_stl_reverse_iterator_base<typename traits::const_iterator>;
|
||||||
|
friend class indexed_based_stl_reverse_iterator_base<typename traits::non_const_iterator>;
|
||||||
|
public:
|
||||||
|
typedef Index difference_type;
|
||||||
|
typedef std::random_access_iterator_tag iterator_category;
|
||||||
|
|
||||||
|
indexed_based_stl_reverse_iterator_base() : mp_xpr(0), m_index(0) {}
|
||||||
|
indexed_based_stl_reverse_iterator_base(XprType& xpr, Index index) : mp_xpr(&xpr), m_index(index) {}
|
||||||
|
|
||||||
|
indexed_based_stl_reverse_iterator_base(const non_const_iterator& other)
|
||||||
|
: mp_xpr(other.mp_xpr), m_index(other.m_index)
|
||||||
|
{}
|
||||||
|
|
||||||
|
indexed_based_stl_reverse_iterator_base& operator=(const non_const_iterator& other)
|
||||||
|
{
|
||||||
|
mp_xpr = other.mp_xpr;
|
||||||
|
m_index = other.m_index;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Derived& operator++() { --m_index; return derived(); }
|
||||||
|
Derived& operator--() { ++m_index; return derived(); }
|
||||||
|
|
||||||
|
Derived operator++(int) { Derived prev(derived()); operator++(); return prev;}
|
||||||
|
Derived operator--(int) { Derived prev(derived()); operator--(); return prev;}
|
||||||
|
|
||||||
|
friend Derived operator+(const indexed_based_stl_reverse_iterator_base& a, Index b) { Derived ret(a.derived()); ret += b; return ret; }
|
||||||
|
friend Derived operator-(const indexed_based_stl_reverse_iterator_base& a, Index b) { Derived ret(a.derived()); ret -= b; return ret; }
|
||||||
|
friend Derived operator+(Index a, const indexed_based_stl_reverse_iterator_base& b) { Derived ret(b.derived()); ret += a; return ret; }
|
||||||
|
friend Derived operator-(Index a, const indexed_based_stl_reverse_iterator_base& b) { Derived ret(b.derived()); ret -= a; return ret; }
|
||||||
|
|
||||||
|
Derived& operator+=(Index b) { m_index -= b; return derived(); }
|
||||||
|
Derived& operator-=(Index b) { m_index += b; return derived(); }
|
||||||
|
|
||||||
|
difference_type operator-(const indexed_based_stl_reverse_iterator_base& other) const
|
||||||
|
{
|
||||||
|
eigen_assert(mp_xpr == other.mp_xpr);
|
||||||
|
return other.m_index - m_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
difference_type operator-(const other_iterator& other) const
|
||||||
|
{
|
||||||
|
eigen_assert(mp_xpr == other.mp_xpr);
|
||||||
|
return other.m_index - m_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index == other.m_index; }
|
||||||
|
bool operator!=(const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index != other.m_index; }
|
||||||
|
bool operator< (const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index > other.m_index; }
|
||||||
|
bool operator<=(const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index >= other.m_index; }
|
||||||
|
bool operator> (const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index < other.m_index; }
|
||||||
|
bool operator>=(const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index <= other.m_index; }
|
||||||
|
|
||||||
|
bool operator==(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index == other.m_index; }
|
||||||
|
bool operator!=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index != other.m_index; }
|
||||||
|
bool operator< (const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index > other.m_index; }
|
||||||
|
bool operator<=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index >= other.m_index; }
|
||||||
|
bool operator> (const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index < other.m_index; }
|
||||||
|
bool operator>=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index <= other.m_index; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
Derived& derived() { return static_cast<Derived&>(*this); }
|
||||||
|
const Derived& derived() const { return static_cast<const Derived&>(*this); }
|
||||||
|
|
||||||
|
XprType *mp_xpr;
|
||||||
|
Index m_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename XprType>
|
||||||
|
class pointer_based_stl_iterator
|
||||||
|
{
|
||||||
|
enum { is_lvalue = internal::is_lvalue<XprType>::value };
|
||||||
|
typedef pointer_based_stl_iterator<typename internal::remove_const<XprType>::type> non_const_iterator;
|
||||||
|
typedef pointer_based_stl_iterator<typename internal::add_const<XprType>::type> const_iterator;
|
||||||
|
typedef typename internal::conditional<internal::is_const<XprType>::value,non_const_iterator,const_iterator>::type other_iterator;
|
||||||
|
// NOTE: in C++03 we cannot declare friend classes through typedefs because we need to write friend class:
|
||||||
|
friend class pointer_based_stl_iterator<typename internal::add_const<XprType>::type>;
|
||||||
|
friend class pointer_based_stl_iterator<typename internal::remove_const<XprType>::type>;
|
||||||
|
public:
|
||||||
|
typedef Index difference_type;
|
||||||
|
typedef typename XprType::Scalar value_type;
|
||||||
|
typedef std::random_access_iterator_tag iterator_category;
|
||||||
|
typedef typename internal::conditional<bool(is_lvalue), value_type*, const value_type*>::type pointer;
|
||||||
|
typedef typename internal::conditional<bool(is_lvalue), value_type&, const value_type&>::type reference;
|
||||||
|
|
||||||
|
|
||||||
|
pointer_based_stl_iterator() EIGEN_NO_THROW : m_ptr(0) {}
|
||||||
|
pointer_based_stl_iterator(XprType& xpr, Index index) EIGEN_NO_THROW : m_incr(xpr.innerStride())
|
||||||
|
{
|
||||||
|
m_ptr = xpr.data() + index * m_incr.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer_based_stl_iterator(const non_const_iterator& other) EIGEN_NO_THROW
|
||||||
|
: m_ptr(other.m_ptr), m_incr(other.m_incr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
pointer_based_stl_iterator& operator=(const non_const_iterator& other) EIGEN_NO_THROW
|
||||||
|
{
|
||||||
|
m_ptr = other.m_ptr;
|
||||||
|
m_incr.setValue(other.m_incr);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
reference operator*() const { return *m_ptr; }
|
||||||
|
reference operator[](Index i) const { return *(m_ptr+i*m_incr.value()); }
|
||||||
|
pointer operator->() const { return m_ptr; }
|
||||||
|
|
||||||
|
pointer_based_stl_iterator& operator++() { m_ptr += m_incr.value(); return *this; }
|
||||||
|
pointer_based_stl_iterator& operator--() { m_ptr -= m_incr.value(); return *this; }
|
||||||
|
|
||||||
|
pointer_based_stl_iterator operator++(int) { pointer_based_stl_iterator prev(*this); operator++(); return prev;}
|
||||||
|
pointer_based_stl_iterator operator--(int) { pointer_based_stl_iterator prev(*this); operator--(); return prev;}
|
||||||
|
|
||||||
|
friend pointer_based_stl_iterator operator+(const pointer_based_stl_iterator& a, Index b) { pointer_based_stl_iterator ret(a); ret += b; return ret; }
|
||||||
|
friend pointer_based_stl_iterator operator-(const pointer_based_stl_iterator& a, Index b) { pointer_based_stl_iterator ret(a); ret -= b; return ret; }
|
||||||
|
friend pointer_based_stl_iterator operator+(Index a, const pointer_based_stl_iterator& b) { pointer_based_stl_iterator ret(b); ret += a; return ret; }
|
||||||
|
friend pointer_based_stl_iterator operator-(Index a, const pointer_based_stl_iterator& b) { pointer_based_stl_iterator ret(b); ret -= a; return ret; }
|
||||||
|
|
||||||
|
pointer_based_stl_iterator& operator+=(Index b) { m_ptr += b*m_incr.value(); return *this; }
|
||||||
|
pointer_based_stl_iterator& operator-=(Index b) { m_ptr -= b*m_incr.value(); return *this; }
|
||||||
|
|
||||||
|
difference_type operator-(const pointer_based_stl_iterator& other) const {
|
||||||
|
return (m_ptr - other.m_ptr)/m_incr.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
difference_type operator-(const other_iterator& other) const {
|
||||||
|
return (m_ptr - other.m_ptr)/m_incr.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const pointer_based_stl_iterator& other) const { return m_ptr == other.m_ptr; }
|
||||||
|
bool operator!=(const pointer_based_stl_iterator& other) const { return m_ptr != other.m_ptr; }
|
||||||
|
bool operator< (const pointer_based_stl_iterator& other) const { return m_ptr < other.m_ptr; }
|
||||||
|
bool operator<=(const pointer_based_stl_iterator& other) const { return m_ptr <= other.m_ptr; }
|
||||||
|
bool operator> (const pointer_based_stl_iterator& other) const { return m_ptr > other.m_ptr; }
|
||||||
|
bool operator>=(const pointer_based_stl_iterator& other) const { return m_ptr >= other.m_ptr; }
|
||||||
|
|
||||||
|
bool operator==(const other_iterator& other) const { return m_ptr == other.m_ptr; }
|
||||||
|
bool operator!=(const other_iterator& other) const { return m_ptr != other.m_ptr; }
|
||||||
|
bool operator< (const other_iterator& other) const { return m_ptr < other.m_ptr; }
|
||||||
|
bool operator<=(const other_iterator& other) const { return m_ptr <= other.m_ptr; }
|
||||||
|
bool operator> (const other_iterator& other) const { return m_ptr > other.m_ptr; }
|
||||||
|
bool operator>=(const other_iterator& other) const { return m_ptr >= other.m_ptr; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
pointer m_ptr;
|
||||||
|
internal::variable_if_dynamic<Index, XprType::InnerStrideAtCompileTime> m_incr;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename _XprType>
|
||||||
|
struct indexed_based_stl_iterator_traits<generic_randaccess_stl_iterator<_XprType> >
|
||||||
|
{
|
||||||
|
typedef _XprType XprType;
|
||||||
|
typedef generic_randaccess_stl_iterator<typename internal::remove_const<XprType>::type> non_const_iterator;
|
||||||
|
typedef generic_randaccess_stl_iterator<typename internal::add_const<XprType>::type> const_iterator;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename XprType>
|
||||||
|
class generic_randaccess_stl_iterator : public indexed_based_stl_iterator_base<generic_randaccess_stl_iterator<XprType> >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename XprType::Scalar value_type;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
enum {
|
||||||
|
has_direct_access = (internal::traits<XprType>::Flags & DirectAccessBit) ? 1 : 0,
|
||||||
|
is_lvalue = internal::is_lvalue<XprType>::value
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef indexed_based_stl_iterator_base<generic_randaccess_stl_iterator> Base;
|
||||||
|
using Base::m_index;
|
||||||
|
using Base::mp_xpr;
|
||||||
|
|
||||||
|
// TODO currently const Transpose/Reshape expressions never returns const references,
|
||||||
|
// so lets return by value too.
|
||||||
|
//typedef typename internal::conditional<bool(has_direct_access), const value_type&, const value_type>::type read_only_ref_t;
|
||||||
|
typedef const value_type read_only_ref_t;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef typename internal::conditional<bool(is_lvalue), value_type *, const value_type *>::type pointer;
|
||||||
|
typedef typename internal::conditional<bool(is_lvalue), value_type&, read_only_ref_t>::type reference;
|
||||||
|
|
||||||
|
generic_randaccess_stl_iterator() : Base() {}
|
||||||
|
generic_randaccess_stl_iterator(XprType& xpr, Index index) : Base(xpr,index) {}
|
||||||
|
generic_randaccess_stl_iterator(const typename Base::non_const_iterator& other) : Base(other) {}
|
||||||
|
using Base::operator=;
|
||||||
|
|
||||||
|
reference operator*() const { return (*mp_xpr)(m_index); }
|
||||||
|
reference operator[](Index i) const { return (*mp_xpr)(m_index+i); }
|
||||||
|
pointer operator->() const { return &((*mp_xpr)(m_index)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename _XprType, DirectionType Direction>
|
||||||
|
struct indexed_based_stl_iterator_traits<subvector_stl_iterator<_XprType,Direction> >
|
||||||
|
{
|
||||||
|
typedef _XprType XprType;
|
||||||
|
typedef subvector_stl_iterator<typename internal::remove_const<XprType>::type, Direction> non_const_iterator;
|
||||||
|
typedef subvector_stl_iterator<typename internal::add_const<XprType>::type, Direction> const_iterator;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename XprType, DirectionType Direction>
|
||||||
|
class subvector_stl_iterator : public indexed_based_stl_iterator_base<subvector_stl_iterator<XprType,Direction> >
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
enum { is_lvalue = internal::is_lvalue<XprType>::value };
|
||||||
|
|
||||||
|
typedef indexed_based_stl_iterator_base<subvector_stl_iterator> Base;
|
||||||
|
using Base::m_index;
|
||||||
|
using Base::mp_xpr;
|
||||||
|
|
||||||
|
typedef typename internal::conditional<Direction==Vertical,typename XprType::ColXpr,typename XprType::RowXpr>::type SubVectorType;
|
||||||
|
typedef typename internal::conditional<Direction==Vertical,typename XprType::ConstColXpr,typename XprType::ConstRowXpr>::type ConstSubVectorType;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef typename internal::conditional<bool(is_lvalue), SubVectorType, ConstSubVectorType>::type reference;
|
||||||
|
typedef typename reference::PlainObject value_type;
|
||||||
|
|
||||||
|
private:
|
||||||
|
class subvector_stl_iterator_ptr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
subvector_stl_iterator_ptr(const reference &subvector) : m_subvector(subvector) {}
|
||||||
|
reference* operator->() { return &m_subvector; }
|
||||||
|
private:
|
||||||
|
reference m_subvector;
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef subvector_stl_iterator_ptr pointer;
|
||||||
|
|
||||||
|
subvector_stl_iterator() : Base() {}
|
||||||
|
subvector_stl_iterator(XprType& xpr, Index index) : Base(xpr,index) {}
|
||||||
|
|
||||||
|
reference operator*() const { return (*mp_xpr).template subVector<Direction>(m_index); }
|
||||||
|
reference operator[](Index i) const { return (*mp_xpr).template subVector<Direction>(m_index+i); }
|
||||||
|
pointer operator->() const { return (*mp_xpr).template subVector<Direction>(m_index); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename _XprType, DirectionType Direction>
|
||||||
|
struct indexed_based_stl_iterator_traits<subvector_stl_reverse_iterator<_XprType,Direction> >
|
||||||
|
{
|
||||||
|
typedef _XprType XprType;
|
||||||
|
typedef subvector_stl_reverse_iterator<typename internal::remove_const<XprType>::type, Direction> non_const_iterator;
|
||||||
|
typedef subvector_stl_reverse_iterator<typename internal::add_const<XprType>::type, Direction> const_iterator;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename XprType, DirectionType Direction>
|
||||||
|
class subvector_stl_reverse_iterator : public indexed_based_stl_reverse_iterator_base<subvector_stl_reverse_iterator<XprType,Direction> >
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
enum { is_lvalue = internal::is_lvalue<XprType>::value };
|
||||||
|
|
||||||
|
typedef indexed_based_stl_reverse_iterator_base<subvector_stl_reverse_iterator> Base;
|
||||||
|
using Base::m_index;
|
||||||
|
using Base::mp_xpr;
|
||||||
|
|
||||||
|
typedef typename internal::conditional<Direction==Vertical,typename XprType::ColXpr,typename XprType::RowXpr>::type SubVectorType;
|
||||||
|
typedef typename internal::conditional<Direction==Vertical,typename XprType::ConstColXpr,typename XprType::ConstRowXpr>::type ConstSubVectorType;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef typename internal::conditional<bool(is_lvalue), SubVectorType, ConstSubVectorType>::type reference;
|
||||||
|
typedef typename reference::PlainObject value_type;
|
||||||
|
|
||||||
|
private:
|
||||||
|
class subvector_stl_reverse_iterator_ptr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
subvector_stl_reverse_iterator_ptr(const reference &subvector) : m_subvector(subvector) {}
|
||||||
|
reference* operator->() { return &m_subvector; }
|
||||||
|
private:
|
||||||
|
reference m_subvector;
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef subvector_stl_reverse_iterator_ptr pointer;
|
||||||
|
|
||||||
|
subvector_stl_reverse_iterator() : Base() {}
|
||||||
|
subvector_stl_reverse_iterator(XprType& xpr, Index index) : Base(xpr,index) {}
|
||||||
|
|
||||||
|
reference operator*() const { return (*mp_xpr).template subVector<Direction>(m_index); }
|
||||||
|
reference operator[](Index i) const { return (*mp_xpr).template subVector<Direction>(m_index+i); }
|
||||||
|
pointer operator->() const { return (*mp_xpr).template subVector<Direction>(m_index); }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
|
||||||
|
/** returns an iterator to the first element of the 1D vector or array
|
||||||
|
* \only_for_vectors
|
||||||
|
* \sa end(), cbegin()
|
||||||
|
*/
|
||||||
|
template<typename Derived>
|
||||||
|
inline typename DenseBase<Derived>::iterator DenseBase<Derived>::begin()
|
||||||
|
{
|
||||||
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
|
||||||
|
return iterator(derived(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** const version of begin() */
|
||||||
|
template<typename Derived>
|
||||||
|
inline typename DenseBase<Derived>::const_iterator DenseBase<Derived>::begin() const
|
||||||
|
{
|
||||||
|
return cbegin();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** returns a read-only const_iterator to the first element of the 1D vector or array
|
||||||
|
* \only_for_vectors
|
||||||
|
* \sa cend(), begin()
|
||||||
|
*/
|
||||||
|
template<typename Derived>
|
||||||
|
inline typename DenseBase<Derived>::const_iterator DenseBase<Derived>::cbegin() const
|
||||||
|
{
|
||||||
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
|
||||||
|
return const_iterator(derived(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** returns an iterator to the element following the last element of the 1D vector or array
|
||||||
|
* \only_for_vectors
|
||||||
|
* \sa begin(), cend()
|
||||||
|
*/
|
||||||
|
template<typename Derived>
|
||||||
|
inline typename DenseBase<Derived>::iterator DenseBase<Derived>::end()
|
||||||
|
{
|
||||||
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
|
||||||
|
return iterator(derived(), size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** const version of end() */
|
||||||
|
template<typename Derived>
|
||||||
|
inline typename DenseBase<Derived>::const_iterator DenseBase<Derived>::end() const
|
||||||
|
{
|
||||||
|
return cend();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** returns a read-only const_iterator to the element following the last element of the 1D vector or array
|
||||||
|
* \only_for_vectors
|
||||||
|
* \sa begin(), cend()
|
||||||
|
*/
|
||||||
|
template<typename Derived>
|
||||||
|
inline typename DenseBase<Derived>::const_iterator DenseBase<Derived>::cend() const
|
||||||
|
{
|
||||||
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
|
||||||
|
return const_iterator(derived(), size());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Eigen
|
||||||
|
|
||||||
|
#endif // EIGEN_STLITERATORS_H
|
||||||
|
|
@ -38,6 +38,10 @@ namespace Eigen {
|
||||||
* \include Map_general_stride.cpp
|
* \include Map_general_stride.cpp
|
||||||
* Output: \verbinclude Map_general_stride.out
|
* Output: \verbinclude Map_general_stride.out
|
||||||
*
|
*
|
||||||
|
* Both strides can be negative, however, a negative stride of -1 cannot be specified at compiletime
|
||||||
|
* because of the ambiguity with Dynamic which is defined to -1 (historically, negative strides were
|
||||||
|
* not allowed).
|
||||||
|
*
|
||||||
* \sa class InnerStride, class OuterStride, \ref TopicStorageOrders
|
* \sa class InnerStride, class OuterStride, \ref TopicStorageOrders
|
||||||
*/
|
*/
|
||||||
template<int _OuterStrideAtCompileTime, int _InnerStrideAtCompileTime>
|
template<int _OuterStrideAtCompileTime, int _InnerStrideAtCompileTime>
|
||||||
|
|
@ -55,6 +59,8 @@ class Stride
|
||||||
Stride()
|
Stride()
|
||||||
: m_outer(OuterStrideAtCompileTime), m_inner(InnerStrideAtCompileTime)
|
: m_outer(OuterStrideAtCompileTime), m_inner(InnerStrideAtCompileTime)
|
||||||
{
|
{
|
||||||
|
// FIXME: for Eigen 4 we should use DynamicIndex instead of Dynamic.
|
||||||
|
// FIXME: for Eigen 4 we should also unify this API with fix<>
|
||||||
eigen_assert(InnerStrideAtCompileTime != Dynamic && OuterStrideAtCompileTime != Dynamic);
|
eigen_assert(InnerStrideAtCompileTime != Dynamic && OuterStrideAtCompileTime != Dynamic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,7 +69,6 @@ class Stride
|
||||||
Stride(Index outerStride, Index innerStride)
|
Stride(Index outerStride, Index innerStride)
|
||||||
: m_outer(outerStride), m_inner(innerStride)
|
: m_outer(outerStride), m_inner(innerStride)
|
||||||
{
|
{
|
||||||
eigen_assert(innerStride>=0 && outerStride>=0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Copy constructor */
|
/** Copy constructor */
|
||||||
|
|
@ -73,10 +78,10 @@ class Stride
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/** \returns the outer stride */
|
/** \returns the outer stride */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index outer() const { return m_outer.value(); }
|
inline Index outer() const { return m_outer.value(); }
|
||||||
/** \returns the inner stride */
|
/** \returns the inner stride */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index inner() const { return m_inner.value(); }
|
inline Index inner() const { return m_inner.value(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
||||||
|
|
@ -30,12 +30,13 @@ public:
|
||||||
typedef typename Base::DstXprType DstXprType;
|
typedef typename Base::DstXprType DstXprType;
|
||||||
typedef swap_assign_op<Scalar> Functor;
|
typedef swap_assign_op<Scalar> Functor;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC generic_dense_assignment_kernel(DstEvaluatorTypeT &dst, const SrcEvaluatorTypeT &src, const Functor &func, DstXprType& dstExpr)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
generic_dense_assignment_kernel(DstEvaluatorTypeT &dst, const SrcEvaluatorTypeT &src, const Functor &func, DstXprType& dstExpr)
|
||||||
: Base(dst, src, func, dstExpr)
|
: Base(dst, src, func, dstExpr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<int StoreMode, int LoadMode, typename PacketType>
|
template<int StoreMode, int LoadMode, typename PacketType>
|
||||||
void assignPacket(Index row, Index col)
|
EIGEN_STRONG_INLINE void assignPacket(Index row, Index col)
|
||||||
{
|
{
|
||||||
PacketType tmp = m_src.template packet<LoadMode,PacketType>(row,col);
|
PacketType tmp = m_src.template packet<LoadMode,PacketType>(row,col);
|
||||||
const_cast<SrcEvaluatorTypeT&>(m_src).template writePacket<LoadMode>(row,col, m_dst.template packet<StoreMode,PacketType>(row,col));
|
const_cast<SrcEvaluatorTypeT&>(m_src).template writePacket<LoadMode>(row,col, m_dst.template packet<StoreMode,PacketType>(row,col));
|
||||||
|
|
@ -43,7 +44,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int StoreMode, int LoadMode, typename PacketType>
|
template<int StoreMode, int LoadMode, typename PacketType>
|
||||||
void assignPacket(Index index)
|
EIGEN_STRONG_INLINE void assignPacket(Index index)
|
||||||
{
|
{
|
||||||
PacketType tmp = m_src.template packet<LoadMode,PacketType>(index);
|
PacketType tmp = m_src.template packet<LoadMode,PacketType>(index);
|
||||||
const_cast<SrcEvaluatorTypeT&>(m_src).template writePacket<LoadMode>(index, m_dst.template packet<StoreMode,PacketType>(index));
|
const_cast<SrcEvaluatorTypeT&>(m_src).template writePacket<LoadMode>(index, m_dst.template packet<StoreMode,PacketType>(index));
|
||||||
|
|
@ -52,7 +53,7 @@ public:
|
||||||
|
|
||||||
// TODO find a simple way not to have to copy/paste this function from generic_dense_assignment_kernel, by simple I mean no CRTP (Gael)
|
// TODO find a simple way not to have to copy/paste this function from generic_dense_assignment_kernel, by simple I mean no CRTP (Gael)
|
||||||
template<int StoreMode, int LoadMode, typename PacketType>
|
template<int StoreMode, int LoadMode, typename PacketType>
|
||||||
void assignPacketByOuterInner(Index outer, Index inner)
|
EIGEN_STRONG_INLINE void assignPacketByOuterInner(Index outer, Index inner)
|
||||||
{
|
{
|
||||||
Index row = Base::rowIndexByOuterInner(outer, inner);
|
Index row = Base::rowIndexByOuterInner(outer, inner);
|
||||||
Index col = Base::colIndexByOuterInner(outer, inner);
|
Index col = Base::colIndexByOuterInner(outer, inner);
|
||||||
|
|
|
||||||
|
|
@ -61,24 +61,27 @@ template<typename MatrixType> class Transpose
|
||||||
typedef typename internal::remove_all<MatrixType>::type NestedExpression;
|
typedef typename internal::remove_all<MatrixType>::type NestedExpression;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
explicit inline Transpose(MatrixType& matrix) : m_matrix(matrix) {}
|
explicit EIGEN_STRONG_INLINE Transpose(MatrixType& matrix) : m_matrix(matrix) {}
|
||||||
|
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Transpose)
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Transpose)
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline Index rows() const { return m_matrix.cols(); }
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
EIGEN_DEVICE_FUNC inline Index cols() const { return m_matrix.rows(); }
|
Index rows() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||||
|
Index cols() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
|
||||||
|
|
||||||
/** \returns the nested expression */
|
/** \returns the nested expression */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
const typename internal::remove_all<MatrixTypeNested>::type&
|
const typename internal::remove_all<MatrixTypeNested>::type&
|
||||||
nestedExpression() const { return m_matrix; }
|
nestedExpression() const { return m_matrix; }
|
||||||
|
|
||||||
/** \returns the nested expression */
|
/** \returns the nested expression */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
typename internal::remove_reference<MatrixTypeNested>::type&
|
typename internal::remove_reference<MatrixTypeNested>::type&
|
||||||
nestedExpression() { return m_matrix; }
|
nestedExpression() { return m_matrix; }
|
||||||
|
|
||||||
/** \internal */
|
/** \internal */
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
void resize(Index nrows, Index ncols) {
|
void resize(Index nrows, Index ncols) {
|
||||||
m_matrix.resize(ncols,nrows);
|
m_matrix.resize(ncols,nrows);
|
||||||
}
|
}
|
||||||
|
|
@ -122,8 +125,10 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE(Transpose<MatrixType>)
|
EIGEN_DENSE_PUBLIC_INTERFACE(Transpose<MatrixType>)
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TransposeImpl)
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TransposeImpl)
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline Index innerStride() const { return derived().nestedExpression().innerStride(); }
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
EIGEN_DEVICE_FUNC inline Index outerStride() const { return derived().nestedExpression().outerStride(); }
|
Index innerStride() const { return derived().nestedExpression().innerStride(); }
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
Index outerStride() const { return derived().nestedExpression().outerStride(); }
|
||||||
|
|
||||||
typedef typename internal::conditional<
|
typedef typename internal::conditional<
|
||||||
internal::is_lvalue<MatrixType>::value,
|
internal::is_lvalue<MatrixType>::value,
|
||||||
|
|
@ -131,21 +136,25 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
|
||||||
const Scalar
|
const Scalar
|
||||||
>::type ScalarWithConstIfNotLvalue;
|
>::type ScalarWithConstIfNotLvalue;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline ScalarWithConstIfNotLvalue* data() { return derived().nestedExpression().data(); }
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
EIGEN_DEVICE_FUNC inline const Scalar* data() const { return derived().nestedExpression().data(); }
|
ScalarWithConstIfNotLvalue* data() { return derived().nestedExpression().data(); }
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
const Scalar* data() const { return derived().nestedExpression().data(); }
|
||||||
|
|
||||||
// FIXME: shall we keep the const version of coeffRef?
|
// FIXME: shall we keep the const version of coeffRef?
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
inline const Scalar& coeffRef(Index rowId, Index colId) const
|
const Scalar& coeffRef(Index rowId, Index colId) const
|
||||||
{
|
{
|
||||||
return derived().nestedExpression().coeffRef(colId, rowId);
|
return derived().nestedExpression().coeffRef(colId, rowId);
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
inline const Scalar& coeffRef(Index index) const
|
const Scalar& coeffRef(Index index) const
|
||||||
{
|
{
|
||||||
return derived().nestedExpression().coeffRef(index);
|
return derived().nestedExpression().coeffRef(index);
|
||||||
}
|
}
|
||||||
|
protected:
|
||||||
|
EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(TransposeImpl)
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \returns an expression of the transpose of *this.
|
/** \returns an expression of the transpose of *this.
|
||||||
|
|
@ -168,7 +177,8 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
|
||||||
*
|
*
|
||||||
* \sa transposeInPlace(), adjoint() */
|
* \sa transposeInPlace(), adjoint() */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline Transpose<Derived>
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
Transpose<Derived>
|
||||||
DenseBase<Derived>::transpose()
|
DenseBase<Derived>::transpose()
|
||||||
{
|
{
|
||||||
return TransposeReturnType(derived());
|
return TransposeReturnType(derived());
|
||||||
|
|
@ -180,7 +190,8 @@ DenseBase<Derived>::transpose()
|
||||||
*
|
*
|
||||||
* \sa transposeInPlace(), adjoint() */
|
* \sa transposeInPlace(), adjoint() */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline typename DenseBase<Derived>::ConstTransposeReturnType
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
|
typename DenseBase<Derived>::ConstTransposeReturnType
|
||||||
DenseBase<Derived>::transpose() const
|
DenseBase<Derived>::transpose() const
|
||||||
{
|
{
|
||||||
return ConstTransposeReturnType(derived());
|
return ConstTransposeReturnType(derived());
|
||||||
|
|
@ -206,7 +217,7 @@ DenseBase<Derived>::transpose() const
|
||||||
*
|
*
|
||||||
* \sa adjointInPlace(), transpose(), conjugate(), class Transpose, class internal::scalar_conjugate_op */
|
* \sa adjointInPlace(), transpose(), conjugate(), class Transpose, class internal::scalar_conjugate_op */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline const typename MatrixBase<Derived>::AdjointReturnType
|
EIGEN_DEVICE_FUNC inline const typename MatrixBase<Derived>::AdjointReturnType
|
||||||
MatrixBase<Derived>::adjoint() const
|
MatrixBase<Derived>::adjoint() const
|
||||||
{
|
{
|
||||||
return AdjointReturnType(this->transpose());
|
return AdjointReturnType(this->transpose());
|
||||||
|
|
@ -228,11 +239,10 @@ struct inplace_transpose_selector;
|
||||||
template<typename MatrixType>
|
template<typename MatrixType>
|
||||||
struct inplace_transpose_selector<MatrixType,true,false> { // square matrix
|
struct inplace_transpose_selector<MatrixType,true,false> { // square matrix
|
||||||
static void run(MatrixType& m) {
|
static void run(MatrixType& m) {
|
||||||
m.matrix().template triangularView<StrictlyUpper>().swap(m.matrix().transpose());
|
m.matrix().template triangularView<StrictlyUpper>().swap(m.matrix().transpose().template triangularView<StrictlyUpper>());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: vectorized path is currently limited to LargestPacketSize x LargestPacketSize cases only.
|
|
||||||
template<typename MatrixType>
|
template<typename MatrixType>
|
||||||
struct inplace_transpose_selector<MatrixType,true,true> { // PacketSize x PacketSize
|
struct inplace_transpose_selector<MatrixType,true,true> { // PacketSize x PacketSize
|
||||||
static void run(MatrixType& m) {
|
static void run(MatrixType& m) {
|
||||||
|
|
@ -249,16 +259,66 @@ struct inplace_transpose_selector<MatrixType,true,true> { // PacketSize x Packet
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename MatrixType, Index Alignment>
|
||||||
|
void BlockedInPlaceTranspose(MatrixType& m) {
|
||||||
|
typedef typename MatrixType::Scalar Scalar;
|
||||||
|
typedef typename internal::packet_traits<typename MatrixType::Scalar>::type Packet;
|
||||||
|
const Index PacketSize = internal::packet_traits<Scalar>::size;
|
||||||
|
eigen_assert(m.rows() == m.cols());
|
||||||
|
int row_start = 0;
|
||||||
|
for (; row_start + PacketSize <= m.rows(); row_start += PacketSize) {
|
||||||
|
for (int col_start = row_start; col_start + PacketSize <= m.cols(); col_start += PacketSize) {
|
||||||
|
PacketBlock<Packet> A;
|
||||||
|
if (row_start == col_start) {
|
||||||
|
for (Index i=0; i<PacketSize; ++i)
|
||||||
|
A.packet[i] = m.template packetByOuterInner<Alignment>(row_start + i,col_start);
|
||||||
|
internal::ptranspose(A);
|
||||||
|
for (Index i=0; i<PacketSize; ++i)
|
||||||
|
m.template writePacket<Alignment>(m.rowIndexByOuterInner(row_start + i, col_start), m.colIndexByOuterInner(row_start + i,col_start), A.packet[i]);
|
||||||
|
} else {
|
||||||
|
PacketBlock<Packet> B;
|
||||||
|
for (Index i=0; i<PacketSize; ++i) {
|
||||||
|
A.packet[i] = m.template packetByOuterInner<Alignment>(row_start + i,col_start);
|
||||||
|
B.packet[i] = m.template packetByOuterInner<Alignment>(col_start + i, row_start);
|
||||||
|
}
|
||||||
|
internal::ptranspose(A);
|
||||||
|
internal::ptranspose(B);
|
||||||
|
for (Index i=0; i<PacketSize; ++i) {
|
||||||
|
m.template writePacket<Alignment>(m.rowIndexByOuterInner(row_start + i, col_start), m.colIndexByOuterInner(row_start + i,col_start), B.packet[i]);
|
||||||
|
m.template writePacket<Alignment>(m.rowIndexByOuterInner(col_start + i, row_start), m.colIndexByOuterInner(col_start + i,row_start), A.packet[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Index row = row_start; row < m.rows(); ++row) {
|
||||||
|
m.matrix().row(row).head(row).swap(
|
||||||
|
m.matrix().col(row).head(row).transpose());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<typename MatrixType,bool MatchPacketSize>
|
template<typename MatrixType,bool MatchPacketSize>
|
||||||
struct inplace_transpose_selector<MatrixType,false,MatchPacketSize> { // non square matrix
|
struct inplace_transpose_selector<MatrixType,false,MatchPacketSize> { // non square or dynamic matrix
|
||||||
static void run(MatrixType& m) {
|
static void run(MatrixType& m) {
|
||||||
if (m.rows()==m.cols())
|
typedef typename MatrixType::Scalar Scalar;
|
||||||
m.matrix().template triangularView<StrictlyUpper>().swap(m.matrix().transpose());
|
if (m.rows() == m.cols()) {
|
||||||
|
const Index PacketSize = internal::packet_traits<Scalar>::size;
|
||||||
|
if (!NumTraits<Scalar>::IsComplex && m.rows() >= PacketSize) {
|
||||||
|
if ((m.rows() % PacketSize) == 0)
|
||||||
|
BlockedInPlaceTranspose<MatrixType,internal::evaluator<MatrixType>::Alignment>(m);
|
||||||
else
|
else
|
||||||
|
BlockedInPlaceTranspose<MatrixType,Unaligned>(m);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m.matrix().template triangularView<StrictlyUpper>().swap(m.matrix().transpose().template triangularView<StrictlyUpper>());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
m = m.transpose().eval();
|
m = m.transpose().eval();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
/** This is the "in place" version of transpose(): it replaces \c *this by its own transpose.
|
/** This is the "in place" version of transpose(): it replaces \c *this by its own transpose.
|
||||||
|
|
@ -281,7 +341,7 @@ struct inplace_transpose_selector<MatrixType,false,MatchPacketSize> { // non squ
|
||||||
*
|
*
|
||||||
* \sa transpose(), adjoint(), adjointInPlace() */
|
* \sa transpose(), adjoint(), adjointInPlace() */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline void DenseBase<Derived>::transposeInPlace()
|
EIGEN_DEVICE_FUNC inline void DenseBase<Derived>::transposeInPlace()
|
||||||
{
|
{
|
||||||
eigen_assert((rows() == cols() || (RowsAtCompileTime == Dynamic && ColsAtCompileTime == Dynamic))
|
eigen_assert((rows() == cols() || (RowsAtCompileTime == Dynamic && ColsAtCompileTime == Dynamic))
|
||||||
&& "transposeInPlace() called on a non-square non-resizable matrix");
|
&& "transposeInPlace() called on a non-square non-resizable matrix");
|
||||||
|
|
@ -312,7 +372,7 @@ inline void DenseBase<Derived>::transposeInPlace()
|
||||||
*
|
*
|
||||||
* \sa transpose(), adjoint(), transposeInPlace() */
|
* \sa transpose(), adjoint(), transposeInPlace() */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline void MatrixBase<Derived>::adjointInPlace()
|
EIGEN_DEVICE_FUNC inline void MatrixBase<Derived>::adjointInPlace()
|
||||||
{
|
{
|
||||||
derived() = adjoint().eval();
|
derived() = adjoint().eval();
|
||||||
}
|
}
|
||||||
|
|
@ -391,6 +451,7 @@ struct checkTransposeAliasing_impl<Derived, OtherDerived, false>
|
||||||
template<typename Dst, typename Src>
|
template<typename Dst, typename Src>
|
||||||
void check_for_aliasing(const Dst &dst, const Src &src)
|
void check_for_aliasing(const Dst &dst, const Src &src)
|
||||||
{
|
{
|
||||||
|
if((!Dst::IsVectorAtCompileTime) && dst.rows()>1 && dst.cols()>1)
|
||||||
internal::checkTransposeAliasing_impl<Dst, Src>::run(dst, src);
|
internal::checkTransposeAliasing_impl<Dst, Src>::run(dst, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,9 @@ class TranspositionsBase
|
||||||
typedef typename IndicesType::Scalar StorageIndex;
|
typedef typename IndicesType::Scalar StorageIndex;
|
||||||
typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
|
typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
Derived& derived() { return *static_cast<Derived*>(this); }
|
Derived& derived() { return *static_cast<Derived*>(this); }
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
const Derived& derived() const { return *static_cast<const Derived*>(this); }
|
const Derived& derived() const { return *static_cast<const Derived*>(this); }
|
||||||
|
|
||||||
/** Copies the \a other transpositions into \c *this */
|
/** Copies the \a other transpositions into \c *this */
|
||||||
|
|
@ -34,25 +36,18 @@ class TranspositionsBase
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
/** This is a special case of the templated operator=. Its purpose is to
|
|
||||||
* prevent a default operator= from hiding the templated operator=.
|
|
||||||
*/
|
|
||||||
Derived& operator=(const TranspositionsBase& other)
|
|
||||||
{
|
|
||||||
indices() = other.indices();
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \returns the number of transpositions */
|
/** \returns the number of transpositions */
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
Index size() const { return indices().size(); }
|
Index size() const { return indices().size(); }
|
||||||
/** \returns the number of rows of the equivalent permutation matrix */
|
/** \returns the number of rows of the equivalent permutation matrix */
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
Index rows() const { return indices().size(); }
|
Index rows() const { return indices().size(); }
|
||||||
/** \returns the number of columns of the equivalent permutation matrix */
|
/** \returns the number of columns of the equivalent permutation matrix */
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
Index cols() const { return indices().size(); }
|
Index cols() const { return indices().size(); }
|
||||||
|
|
||||||
/** Direct access to the underlying index vector */
|
/** Direct access to the underlying index vector */
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
inline const StorageIndex& coeff(Index i) const { return indices().coeff(i); }
|
inline const StorageIndex& coeff(Index i) const { return indices().coeff(i); }
|
||||||
/** Direct access to the underlying index vector */
|
/** Direct access to the underlying index vector */
|
||||||
inline StorageIndex& coeffRef(Index i) { return indices().coeffRef(i); }
|
inline StorageIndex& coeffRef(Index i) { return indices().coeffRef(i); }
|
||||||
|
|
@ -66,8 +61,10 @@ class TranspositionsBase
|
||||||
inline StorageIndex& operator[](Index i) { return indices()(i); }
|
inline StorageIndex& operator[](Index i) { return indices()(i); }
|
||||||
|
|
||||||
/** const version of indices(). */
|
/** const version of indices(). */
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
const IndicesType& indices() const { return derived().indices(); }
|
const IndicesType& indices() const { return derived().indices(); }
|
||||||
/** \returns a reference to the stored array representing the transpositions. */
|
/** \returns a reference to the stored array representing the transpositions. */
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
IndicesType& indices() { return derived().indices(); }
|
IndicesType& indices() { return derived().indices(); }
|
||||||
|
|
||||||
/** Resizes to given size. */
|
/** Resizes to given size. */
|
||||||
|
|
@ -84,7 +81,7 @@ class TranspositionsBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: do we want such methods ?
|
// FIXME: do we want such methods ?
|
||||||
// might be usefull when the target matrix expression is complex, e.g.:
|
// might be useful when the target matrix expression is complex, e.g.:
|
||||||
// object.matrix().block(..,..,..,..) = trans * object.matrix().block(..,..,..,..);
|
// object.matrix().block(..,..,..,..) = trans * object.matrix().block(..,..,..,..);
|
||||||
/*
|
/*
|
||||||
template<typename MatrixType>
|
template<typename MatrixType>
|
||||||
|
|
@ -171,12 +168,6 @@ class Transpositions : public TranspositionsBase<Transpositions<SizeAtCompileTim
|
||||||
inline Transpositions(const TranspositionsBase<OtherDerived>& other)
|
inline Transpositions(const TranspositionsBase<OtherDerived>& other)
|
||||||
: m_indices(other.indices()) {}
|
: m_indices(other.indices()) {}
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
/** Standard copy constructor. Defined only to prevent a default copy constructor
|
|
||||||
* from hiding the other templated constructor */
|
|
||||||
inline Transpositions(const Transpositions& other) : m_indices(other.indices()) {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Generic constructor from expression of the transposition indices. */
|
/** Generic constructor from expression of the transposition indices. */
|
||||||
template<typename Other>
|
template<typename Other>
|
||||||
explicit inline Transpositions(const MatrixBase<Other>& indices) : m_indices(indices)
|
explicit inline Transpositions(const MatrixBase<Other>& indices) : m_indices(indices)
|
||||||
|
|
@ -189,25 +180,16 @@ class Transpositions : public TranspositionsBase<Transpositions<SizeAtCompileTim
|
||||||
return Base::operator=(other);
|
return Base::operator=(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
/** This is a special case of the templated operator=. Its purpose is to
|
|
||||||
* prevent a default operator= from hiding the templated operator=.
|
|
||||||
*/
|
|
||||||
Transpositions& operator=(const Transpositions& other)
|
|
||||||
{
|
|
||||||
m_indices = other.m_indices;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Constructs an uninitialized permutation matrix of given size.
|
/** Constructs an uninitialized permutation matrix of given size.
|
||||||
*/
|
*/
|
||||||
inline Transpositions(Index size) : m_indices(size)
|
inline Transpositions(Index size) : m_indices(size)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/** const version of indices(). */
|
/** const version of indices(). */
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
const IndicesType& indices() const { return m_indices; }
|
const IndicesType& indices() const { return m_indices; }
|
||||||
/** \returns a reference to the stored array representing the transpositions. */
|
/** \returns a reference to the stored array representing the transpositions. */
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
IndicesType& indices() { return m_indices; }
|
IndicesType& indices() { return m_indices; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -265,9 +247,11 @@ class Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,_StorageIndex>,P
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** const version of indices(). */
|
/** const version of indices(). */
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
const IndicesType& indices() const { return m_indices; }
|
const IndicesType& indices() const { return m_indices; }
|
||||||
|
|
||||||
/** \returns a reference to the stored array representing the transpositions. */
|
/** \returns a reference to the stored array representing the transpositions. */
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
IndicesType& indices() { return m_indices; }
|
IndicesType& indices() { return m_indices; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -306,21 +290,12 @@ class TranspositionsWrapper
|
||||||
return Base::operator=(other);
|
return Base::operator=(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
/** This is a special case of the templated operator=. Its purpose is to
|
|
||||||
* prevent a default operator= from hiding the templated operator=.
|
|
||||||
*/
|
|
||||||
TranspositionsWrapper& operator=(const TranspositionsWrapper& other)
|
|
||||||
{
|
|
||||||
m_indices = other.m_indices;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** const version of indices(). */
|
/** const version of indices(). */
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
const IndicesType& indices() const { return m_indices; }
|
const IndicesType& indices() const { return m_indices; }
|
||||||
|
|
||||||
/** \returns a reference to the stored array representing the transpositions. */
|
/** \returns a reference to the stored array representing the transpositions. */
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
IndicesType& indices() { return m_indices; }
|
IndicesType& indices() { return m_indices; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -374,9 +349,12 @@ class Transpose<TranspositionsBase<TranspositionsDerived> >
|
||||||
|
|
||||||
explicit Transpose(const TranspositionType& t) : m_transpositions(t) {}
|
explicit Transpose(const TranspositionType& t) : m_transpositions(t) {}
|
||||||
|
|
||||||
Index size() const { return m_transpositions.size(); }
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
Index rows() const { return m_transpositions.size(); }
|
Index size() const EIGEN_NOEXCEPT { return m_transpositions.size(); }
|
||||||
Index cols() const { return m_transpositions.size(); }
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
|
Index rows() const EIGEN_NOEXCEPT { return m_transpositions.size(); }
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
|
Index cols() const EIGEN_NOEXCEPT { return m_transpositions.size(); }
|
||||||
|
|
||||||
/** \returns the \a matrix with the inverse transpositions applied to the columns.
|
/** \returns the \a matrix with the inverse transpositions applied to the columns.
|
||||||
*/
|
*/
|
||||||
|
|
@ -396,6 +374,7 @@ class Transpose<TranspositionsBase<TranspositionsDerived> >
|
||||||
return Product<Transpose, OtherDerived, AliasFreeProduct>(*this, matrix.derived());
|
return Product<Transpose, OtherDerived, AliasFreeProduct>(*this, matrix.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
const TranspositionType& nestedExpression() const { return m_transpositions; }
|
const TranspositionType& nestedExpression() const { return m_transpositions; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
||||||
|
|
@ -53,18 +53,19 @@ template<typename Derived> class TriangularBase : public EigenBase<Derived>
|
||||||
typedef Derived const& Nested;
|
typedef Derived const& Nested;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline TriangularBase() { eigen_assert(!((Mode&UnitDiag) && (Mode&ZeroDiag))); }
|
inline TriangularBase() { eigen_assert(!((int(Mode) & int(UnitDiag)) && (int(Mode) & int(ZeroDiag)))); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index rows() const { return derived().rows(); }
|
inline Index rows() const EIGEN_NOEXCEPT { return derived().rows(); }
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index cols() const { return derived().cols(); }
|
inline Index cols() const EIGEN_NOEXCEPT { return derived().cols(); }
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index outerStride() const { return derived().outerStride(); }
|
inline Index outerStride() const EIGEN_NOEXCEPT { return derived().outerStride(); }
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index innerStride() const { return derived().innerStride(); }
|
inline Index innerStride() const EIGEN_NOEXCEPT { return derived().innerStride(); }
|
||||||
|
|
||||||
// dummy resize function
|
// dummy resize function
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
void resize(Index rows, Index cols)
|
void resize(Index rows, Index cols)
|
||||||
{
|
{
|
||||||
EIGEN_UNUSED_VARIABLE(rows);
|
EIGEN_UNUSED_VARIABLE(rows);
|
||||||
|
|
@ -197,6 +198,7 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
|
||||||
typedef typename internal::traits<TriangularView>::MatrixTypeNestedNonRef MatrixTypeNestedNonRef;
|
typedef typename internal::traits<TriangularView>::MatrixTypeNestedNonRef MatrixTypeNestedNonRef;
|
||||||
|
|
||||||
typedef typename internal::remove_all<typename MatrixType::ConjugateReturnType>::type MatrixConjugateReturnType;
|
typedef typename internal::remove_all<typename MatrixType::ConjugateReturnType>::type MatrixConjugateReturnType;
|
||||||
|
typedef TriangularView<typename internal::add_const<MatrixType>::type, _Mode> ConstTriangularView;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
@ -217,16 +219,14 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
|
||||||
explicit inline TriangularView(MatrixType& matrix) : m_matrix(matrix)
|
explicit inline TriangularView(MatrixType& matrix) : m_matrix(matrix)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
using Base::operator=;
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TriangularView)
|
||||||
TriangularView& operator=(const TriangularView &other)
|
|
||||||
{ return Base::operator=(other); }
|
|
||||||
|
|
||||||
/** \copydoc EigenBase::rows() */
|
/** \copydoc EigenBase::rows() */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index rows() const { return m_matrix.rows(); }
|
inline Index rows() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
|
||||||
/** \copydoc EigenBase::cols() */
|
/** \copydoc EigenBase::cols() */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
inline Index cols() const { return m_matrix.cols(); }
|
inline Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
|
||||||
|
|
||||||
/** \returns a const reference to the nested expression */
|
/** \returns a const reference to the nested expression */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
|
|
@ -242,6 +242,18 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
|
||||||
inline const ConjugateReturnType conjugate() const
|
inline const ConjugateReturnType conjugate() const
|
||||||
{ return ConjugateReturnType(m_matrix.conjugate()); }
|
{ return ConjugateReturnType(m_matrix.conjugate()); }
|
||||||
|
|
||||||
|
/** \returns an expression of the complex conjugate of \c *this if Cond==true,
|
||||||
|
* returns \c *this otherwise.
|
||||||
|
*/
|
||||||
|
template<bool Cond>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
inline typename internal::conditional<Cond,ConjugateReturnType,ConstTriangularView>::type
|
||||||
|
conjugateIf() const
|
||||||
|
{
|
||||||
|
typedef typename internal::conditional<Cond,ConjugateReturnType,ConstTriangularView>::type ReturnType;
|
||||||
|
return ReturnType(m_matrix.template conjugateIf<Cond>());
|
||||||
|
}
|
||||||
|
|
||||||
typedef TriangularView<const typename MatrixType::AdjointReturnType,TransposeMode> AdjointReturnType;
|
typedef TriangularView<const typename MatrixType::AdjointReturnType,TransposeMode> AdjointReturnType;
|
||||||
/** \sa MatrixBase::adjoint() const */
|
/** \sa MatrixBase::adjoint() const */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
|
|
@ -435,14 +447,14 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
||||||
TriangularViewType& operator=(const TriangularViewImpl& other)
|
TriangularViewType& operator=(const TriangularViewImpl& other)
|
||||||
{ return *this = other.derived().nestedExpression(); }
|
{ return *this = other.derived().nestedExpression(); }
|
||||||
|
|
||||||
/** \deprecated */
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
/** \deprecated */
|
||||||
|
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC
|
||||||
void lazyAssign(const TriangularBase<OtherDerived>& other);
|
void lazyAssign(const TriangularBase<OtherDerived>& other);
|
||||||
|
|
||||||
/** @deprecated */
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
/** \deprecated */
|
||||||
|
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC
|
||||||
void lazyAssign(const MatrixBase<OtherDerived>& other);
|
void lazyAssign(const MatrixBase<OtherDerived>& other);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -470,7 +482,7 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
||||||
* \a Side==OnTheLeft (the default), or the right-inverse-multiply \a other * inverse(\c *this) if
|
* \a Side==OnTheLeft (the default), or the right-inverse-multiply \a other * inverse(\c *this) if
|
||||||
* \a Side==OnTheRight.
|
* \a Side==OnTheRight.
|
||||||
*
|
*
|
||||||
* Note that the template parameter \c Side can be ommitted, in which case \c Side==OnTheLeft
|
* Note that the template parameter \c Side can be omitted, in which case \c Side==OnTheLeft
|
||||||
*
|
*
|
||||||
* The matrix \c *this must be triangular and invertible (i.e., all the coefficients of the
|
* The matrix \c *this must be triangular and invertible (i.e., all the coefficients of the
|
||||||
* diagonal must be non zero). It works as a forward (resp. backward) substitution if \c *this
|
* diagonal must be non zero). It works as a forward (resp. backward) substitution if \c *this
|
||||||
|
|
@ -488,7 +500,6 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
||||||
* \sa TriangularView::solveInPlace()
|
* \sa TriangularView::solveInPlace()
|
||||||
*/
|
*/
|
||||||
template<int Side, typename Other>
|
template<int Side, typename Other>
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline const internal::triangular_solve_retval<Side,TriangularViewType, Other>
|
inline const internal::triangular_solve_retval<Side,TriangularViewType, Other>
|
||||||
solve(const MatrixBase<Other>& other) const;
|
solve(const MatrixBase<Other>& other) const;
|
||||||
|
|
||||||
|
|
@ -497,7 +508,7 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
||||||
* \warning The parameter is only marked 'const' to make the C++ compiler accept a temporary expression here.
|
* \warning The parameter is only marked 'const' to make the C++ compiler accept a temporary expression here.
|
||||||
* This function will const_cast it, so constness isn't honored here.
|
* This function will const_cast it, so constness isn't honored here.
|
||||||
*
|
*
|
||||||
* Note that the template parameter \c Side can be ommitted, in which case \c Side==OnTheLeft
|
* Note that the template parameter \c Side can be omitted, in which case \c Side==OnTheLeft
|
||||||
*
|
*
|
||||||
* See TriangularView:solve() for the details.
|
* See TriangularView:solve() for the details.
|
||||||
*/
|
*/
|
||||||
|
|
@ -523,10 +534,10 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
||||||
call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
|
call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @deprecated
|
/** Shortcut for \code (*this).swap(other.triangularView<(*this)::Mode>()) \endcode */
|
||||||
* Shortcut for \code (*this).swap(other.triangularView<(*this)::Mode>()) \endcode */
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
/** \deprecated */
|
||||||
|
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC
|
||||||
void swap(MatrixBase<OtherDerived> const & other)
|
void swap(MatrixBase<OtherDerived> const & other)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_LVALUE(OtherDerived);
|
EIGEN_STATIC_ASSERT_LVALUE(OtherDerived);
|
||||||
|
|
@ -544,6 +555,10 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
||||||
template<typename ProductType>
|
template<typename ProductType>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
EIGEN_STRONG_INLINE TriangularViewType& _assignProduct(const ProductType& prod, const Scalar& alpha, bool beta);
|
EIGEN_STRONG_INLINE TriangularViewType& _assignProduct(const ProductType& prod, const Scalar& alpha, bool beta);
|
||||||
|
protected:
|
||||||
|
EIGEN_DEFAULT_COPY_CONSTRUCTOR(TriangularViewImpl)
|
||||||
|
EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(TriangularViewImpl)
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
|
|
@ -554,7 +569,7 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
||||||
// FIXME should we keep that possibility
|
// FIXME should we keep that possibility
|
||||||
template<typename MatrixType, unsigned int Mode>
|
template<typename MatrixType, unsigned int Mode>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
inline TriangularView<MatrixType, Mode>&
|
EIGEN_DEVICE_FUNC inline TriangularView<MatrixType, Mode>&
|
||||||
TriangularViewImpl<MatrixType, Mode, Dense>::operator=(const MatrixBase<OtherDerived>& other)
|
TriangularViewImpl<MatrixType, Mode, Dense>::operator=(const MatrixBase<OtherDerived>& other)
|
||||||
{
|
{
|
||||||
internal::call_assignment_no_alias(derived(), other.derived(), internal::assign_op<Scalar,typename OtherDerived::Scalar>());
|
internal::call_assignment_no_alias(derived(), other.derived(), internal::assign_op<Scalar,typename OtherDerived::Scalar>());
|
||||||
|
|
@ -564,7 +579,7 @@ TriangularViewImpl<MatrixType, Mode, Dense>::operator=(const MatrixBase<OtherDer
|
||||||
// FIXME should we keep that possibility
|
// FIXME should we keep that possibility
|
||||||
template<typename MatrixType, unsigned int Mode>
|
template<typename MatrixType, unsigned int Mode>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(const MatrixBase<OtherDerived>& other)
|
EIGEN_DEVICE_FUNC void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(const MatrixBase<OtherDerived>& other)
|
||||||
{
|
{
|
||||||
internal::call_assignment_no_alias(derived(), other.template triangularView<Mode>());
|
internal::call_assignment_no_alias(derived(), other.template triangularView<Mode>());
|
||||||
}
|
}
|
||||||
|
|
@ -573,7 +588,7 @@ void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(const MatrixBase<Ot
|
||||||
|
|
||||||
template<typename MatrixType, unsigned int Mode>
|
template<typename MatrixType, unsigned int Mode>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
inline TriangularView<MatrixType, Mode>&
|
EIGEN_DEVICE_FUNC inline TriangularView<MatrixType, Mode>&
|
||||||
TriangularViewImpl<MatrixType, Mode, Dense>::operator=(const TriangularBase<OtherDerived>& other)
|
TriangularViewImpl<MatrixType, Mode, Dense>::operator=(const TriangularBase<OtherDerived>& other)
|
||||||
{
|
{
|
||||||
eigen_assert(Mode == int(OtherDerived::Mode));
|
eigen_assert(Mode == int(OtherDerived::Mode));
|
||||||
|
|
@ -583,7 +598,7 @@ TriangularViewImpl<MatrixType, Mode, Dense>::operator=(const TriangularBase<Othe
|
||||||
|
|
||||||
template<typename MatrixType, unsigned int Mode>
|
template<typename MatrixType, unsigned int Mode>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(const TriangularBase<OtherDerived>& other)
|
EIGEN_DEVICE_FUNC void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(const TriangularBase<OtherDerived>& other)
|
||||||
{
|
{
|
||||||
eigen_assert(Mode == int(OtherDerived::Mode));
|
eigen_assert(Mode == int(OtherDerived::Mode));
|
||||||
internal::call_assignment_no_alias(derived(), other.derived());
|
internal::call_assignment_no_alias(derived(), other.derived());
|
||||||
|
|
@ -598,7 +613,7 @@ void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(const TriangularBas
|
||||||
* If the matrix is triangular, the opposite part is set to zero. */
|
* If the matrix is triangular, the opposite part is set to zero. */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename DenseDerived>
|
template<typename DenseDerived>
|
||||||
void TriangularBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const
|
EIGEN_DEVICE_FUNC void TriangularBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const
|
||||||
{
|
{
|
||||||
evalToLazy(other.derived());
|
evalToLazy(other.derived());
|
||||||
}
|
}
|
||||||
|
|
@ -624,6 +639,7 @@ void TriangularBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<unsigned int Mode>
|
template<unsigned int Mode>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
typename MatrixBase<Derived>::template TriangularViewReturnType<Mode>::Type
|
typename MatrixBase<Derived>::template TriangularViewReturnType<Mode>::Type
|
||||||
MatrixBase<Derived>::triangularView()
|
MatrixBase<Derived>::triangularView()
|
||||||
{
|
{
|
||||||
|
|
@ -633,6 +649,7 @@ MatrixBase<Derived>::triangularView()
|
||||||
/** This is the const version of MatrixBase::triangularView() */
|
/** This is the const version of MatrixBase::triangularView() */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<unsigned int Mode>
|
template<unsigned int Mode>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
typename MatrixBase<Derived>::template ConstTriangularViewReturnType<Mode>::Type
|
typename MatrixBase<Derived>::template ConstTriangularViewReturnType<Mode>::Type
|
||||||
MatrixBase<Derived>::triangularView() const
|
MatrixBase<Derived>::triangularView() const
|
||||||
{
|
{
|
||||||
|
|
@ -715,6 +732,7 @@ struct unary_evaluator<TriangularView<MatrixType,Mode>, IndexBased>
|
||||||
{
|
{
|
||||||
typedef TriangularView<MatrixType,Mode> XprType;
|
typedef TriangularView<MatrixType,Mode> XprType;
|
||||||
typedef evaluator<typename internal::remove_all<MatrixType>::type> Base;
|
typedef evaluator<typename internal::remove_all<MatrixType>::type> Base;
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
unary_evaluator(const XprType &xpr) : Base(xpr.nestedExpression()) {}
|
unary_evaluator(const XprType &xpr) : Base(xpr.nestedExpression()) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -801,7 +819,7 @@ void call_triangular_assignment_loop(DstXprType& dst, const SrcXprType& src, con
|
||||||
enum {
|
enum {
|
||||||
unroll = DstXprType::SizeAtCompileTime != Dynamic
|
unroll = DstXprType::SizeAtCompileTime != Dynamic
|
||||||
&& SrcEvaluatorType::CoeffReadCost < HugeCost
|
&& SrcEvaluatorType::CoeffReadCost < HugeCost
|
||||||
&& DstXprType::SizeAtCompileTime * (DstEvaluatorType::CoeffReadCost+SrcEvaluatorType::CoeffReadCost) / 2 <= EIGEN_UNROLLING_LIMIT
|
&& DstXprType::SizeAtCompileTime * (int(DstEvaluatorType::CoeffReadCost) + int(SrcEvaluatorType::CoeffReadCost)) / 2 <= EIGEN_UNROLLING_LIMIT
|
||||||
};
|
};
|
||||||
|
|
||||||
triangular_assignment_loop<Kernel, Mode, unroll ? int(DstXprType::SizeAtCompileTime) : Dynamic, SetOpposite>::run(kernel);
|
triangular_assignment_loop<Kernel, Mode, unroll ? int(DstXprType::SizeAtCompileTime) : Dynamic, SetOpposite>::run(kernel);
|
||||||
|
|
@ -835,7 +853,7 @@ struct Assignment<DstXprType, SrcXprType, Functor, Triangular2Dense>
|
||||||
{
|
{
|
||||||
EIGEN_DEVICE_FUNC static void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
|
EIGEN_DEVICE_FUNC static void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
|
||||||
{
|
{
|
||||||
call_triangular_assignment_loop<SrcXprType::Mode, (SrcXprType::Mode&SelfAdjoint)==0>(dst, src, func);
|
call_triangular_assignment_loop<SrcXprType::Mode, (int(SrcXprType::Mode) & int(SelfAdjoint)) == 0>(dst, src, func);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -930,10 +948,10 @@ struct triangular_assignment_loop<Kernel, Mode, Dynamic, SetOpposite>
|
||||||
* If the matrix is triangular, the opposite part is set to zero. */
|
* If the matrix is triangular, the opposite part is set to zero. */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename DenseDerived>
|
template<typename DenseDerived>
|
||||||
void TriangularBase<Derived>::evalToLazy(MatrixBase<DenseDerived> &other) const
|
EIGEN_DEVICE_FUNC void TriangularBase<Derived>::evalToLazy(MatrixBase<DenseDerived> &other) const
|
||||||
{
|
{
|
||||||
other.derived().resize(this->rows(), this->cols());
|
other.derived().resize(this->rows(), this->cols());
|
||||||
internal::call_triangular_assignment_loop<Derived::Mode,(Derived::Mode&SelfAdjoint)==0 /* SetOpposite */>(other.derived(), derived().nestedExpression());
|
internal::call_triangular_assignment_loop<Derived::Mode, (int(Derived::Mode) & int(SelfAdjoint)) == 0 /* SetOpposite */>(other.derived(), derived().nestedExpression());
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
@ -950,7 +968,7 @@ struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::assign_
|
||||||
if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
|
if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
|
||||||
dst.resize(dstRows, dstCols);
|
dst.resize(dstRows, dstCols);
|
||||||
|
|
||||||
dst._assignProduct(src, 1, 0);
|
dst._assignProduct(src, Scalar(1), false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -961,7 +979,7 @@ struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::add_ass
|
||||||
typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
|
typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
|
||||||
static void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<Scalar,typename SrcXprType::Scalar> &)
|
static void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<Scalar,typename SrcXprType::Scalar> &)
|
||||||
{
|
{
|
||||||
dst._assignProduct(src, 1, 1);
|
dst._assignProduct(src, Scalar(1), true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -972,7 +990,7 @@ struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::sub_ass
|
||||||
typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
|
typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
|
||||||
static void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<Scalar,typename SrcXprType::Scalar> &)
|
static void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<Scalar,typename SrcXprType::Scalar> &)
|
||||||
{
|
{
|
||||||
dst._assignProduct(src, -1, 1);
|
dst._assignProduct(src, Scalar(-1), true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ struct traits<VectorBlock<VectorType, Size> >
|
||||||
* It is the return type of DenseBase::segment(Index,Index) and DenseBase::segment<int>(Index) and
|
* It is the return type of DenseBase::segment(Index,Index) and DenseBase::segment<int>(Index) and
|
||||||
* most of the time this is the only way it is used.
|
* most of the time this is the only way it is used.
|
||||||
*
|
*
|
||||||
* However, if you want to directly maniputate sub-vector expressions,
|
* However, if you want to directly manipulate sub-vector expressions,
|
||||||
* for instance if you want to write a function returning such an expression, you
|
* for instance if you want to write a function returning such an expression, you
|
||||||
* will need to use this class.
|
* will need to use this class.
|
||||||
*
|
*
|
||||||
|
|
@ -71,8 +71,8 @@ template<typename VectorType, int Size> class VectorBlock
|
||||||
|
|
||||||
/** Dynamic-size constructor
|
/** Dynamic-size constructor
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
inline VectorBlock(VectorType& vector, Index start, Index size)
|
VectorBlock(VectorType& vector, Index start, Index size)
|
||||||
: Base(vector,
|
: Base(vector,
|
||||||
IsColVector ? start : 0, IsColVector ? 0 : start,
|
IsColVector ? start : 0, IsColVector ? 0 : start,
|
||||||
IsColVector ? size : 1, IsColVector ? 1 : size)
|
IsColVector ? size : 1, IsColVector ? 1 : size)
|
||||||
|
|
@ -82,8 +82,8 @@ template<typename VectorType, int Size> class VectorBlock
|
||||||
|
|
||||||
/** Fixed-size constructor
|
/** Fixed-size constructor
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||||
inline VectorBlock(VectorType& vector, Index start)
|
VectorBlock(VectorType& vector, Index start)
|
||||||
: Base(vector, IsColVector ? start : 0, IsColVector ? 0 : start)
|
: Base(vector, IsColVector ? start : 0, IsColVector ? 0 : start)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorBlock);
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorBlock);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// This file is part of Eigen, a lightweight C++ template library
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
// for linear algebra.
|
// for linear algebra.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
|
// Copyright (C) 2008-2019 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
// This Source Code Form is subject to the terms of the Mozilla
|
||||||
|
|
@ -65,10 +65,10 @@ class PartialReduxExpr : public internal::dense_xpr_base< PartialReduxExpr<Matri
|
||||||
explicit PartialReduxExpr(const MatrixType& mat, const MemberOp& func = MemberOp())
|
explicit PartialReduxExpr(const MatrixType& mat, const MemberOp& func = MemberOp())
|
||||||
: m_matrix(mat), m_functor(func) {}
|
: m_matrix(mat), m_functor(func) {}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
Index rows() const { return (Direction==Vertical ? 1 : m_matrix.rows()); }
|
Index rows() const EIGEN_NOEXCEPT { return (Direction==Vertical ? 1 : m_matrix.rows()); }
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||||
Index cols() const { return (Direction==Horizontal ? 1 : m_matrix.cols()); }
|
Index cols() const EIGEN_NOEXCEPT { return (Direction==Horizontal ? 1 : m_matrix.cols()); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
typename MatrixType::Nested nestedExpression() const { return m_matrix; }
|
typename MatrixType::Nested nestedExpression() const { return m_matrix; }
|
||||||
|
|
@ -81,39 +81,46 @@ class PartialReduxExpr : public internal::dense_xpr_base< PartialReduxExpr<Matri
|
||||||
const MemberOp m_functor;
|
const MemberOp m_functor;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define EIGEN_MEMBER_FUNCTOR(MEMBER,COST) \
|
template<typename A,typename B> struct partial_redux_dummy_func;
|
||||||
template <typename ResultType> \
|
|
||||||
|
#define EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(MEMBER,COST,VECTORIZABLE,BINARYOP) \
|
||||||
|
template <typename ResultType,typename Scalar> \
|
||||||
struct member_##MEMBER { \
|
struct member_##MEMBER { \
|
||||||
EIGEN_EMPTY_STRUCT_CTOR(member_##MEMBER) \
|
EIGEN_EMPTY_STRUCT_CTOR(member_##MEMBER) \
|
||||||
typedef ResultType result_type; \
|
typedef ResultType result_type; \
|
||||||
template<typename Scalar, int Size> struct Cost \
|
typedef BINARYOP<Scalar,Scalar> BinaryOp; \
|
||||||
{ enum { value = COST }; }; \
|
template<int Size> struct Cost { enum { value = COST }; }; \
|
||||||
|
enum { Vectorizable = VECTORIZABLE }; \
|
||||||
template<typename XprType> \
|
template<typename XprType> \
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
|
||||||
ResultType operator()(const XprType& mat) const \
|
ResultType operator()(const XprType& mat) const \
|
||||||
{ return mat.MEMBER(); } \
|
{ return mat.MEMBER(); } \
|
||||||
|
BinaryOp binaryFunc() const { return BinaryOp(); } \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define EIGEN_MEMBER_FUNCTOR(MEMBER,COST) \
|
||||||
|
EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(MEMBER,COST,0,partial_redux_dummy_func)
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
EIGEN_MEMBER_FUNCTOR(squaredNorm, Size * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
|
|
||||||
EIGEN_MEMBER_FUNCTOR(norm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
|
EIGEN_MEMBER_FUNCTOR(norm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
|
||||||
EIGEN_MEMBER_FUNCTOR(stableNorm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
|
EIGEN_MEMBER_FUNCTOR(stableNorm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
|
||||||
EIGEN_MEMBER_FUNCTOR(blueNorm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
|
EIGEN_MEMBER_FUNCTOR(blueNorm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
|
||||||
EIGEN_MEMBER_FUNCTOR(hypotNorm, (Size-1) * functor_traits<scalar_hypot_op<Scalar> >::Cost );
|
EIGEN_MEMBER_FUNCTOR(hypotNorm, (Size-1) * functor_traits<scalar_hypot_op<Scalar> >::Cost );
|
||||||
EIGEN_MEMBER_FUNCTOR(sum, (Size-1)*NumTraits<Scalar>::AddCost);
|
|
||||||
EIGEN_MEMBER_FUNCTOR(mean, (Size-1)*NumTraits<Scalar>::AddCost + NumTraits<Scalar>::MulCost);
|
|
||||||
EIGEN_MEMBER_FUNCTOR(minCoeff, (Size-1)*NumTraits<Scalar>::AddCost);
|
|
||||||
EIGEN_MEMBER_FUNCTOR(maxCoeff, (Size-1)*NumTraits<Scalar>::AddCost);
|
|
||||||
EIGEN_MEMBER_FUNCTOR(all, (Size-1)*NumTraits<Scalar>::AddCost);
|
EIGEN_MEMBER_FUNCTOR(all, (Size-1)*NumTraits<Scalar>::AddCost);
|
||||||
EIGEN_MEMBER_FUNCTOR(any, (Size-1)*NumTraits<Scalar>::AddCost);
|
EIGEN_MEMBER_FUNCTOR(any, (Size-1)*NumTraits<Scalar>::AddCost);
|
||||||
EIGEN_MEMBER_FUNCTOR(count, (Size-1)*NumTraits<Scalar>::AddCost);
|
EIGEN_MEMBER_FUNCTOR(count, (Size-1)*NumTraits<Scalar>::AddCost);
|
||||||
EIGEN_MEMBER_FUNCTOR(prod, (Size-1)*NumTraits<Scalar>::MulCost);
|
|
||||||
|
|
||||||
template <int p, typename ResultType>
|
EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(sum, (Size-1)*NumTraits<Scalar>::AddCost, 1, internal::scalar_sum_op);
|
||||||
|
EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(minCoeff, (Size-1)*NumTraits<Scalar>::AddCost, 1, internal::scalar_min_op);
|
||||||
|
EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(maxCoeff, (Size-1)*NumTraits<Scalar>::AddCost, 1, internal::scalar_max_op);
|
||||||
|
EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(prod, (Size-1)*NumTraits<Scalar>::MulCost, 1, internal::scalar_product_op);
|
||||||
|
|
||||||
|
template <int p, typename ResultType,typename Scalar>
|
||||||
struct member_lpnorm {
|
struct member_lpnorm {
|
||||||
typedef ResultType result_type;
|
typedef ResultType result_type;
|
||||||
template<typename Scalar, int Size> struct Cost
|
enum { Vectorizable = 0 };
|
||||||
|
template<int Size> struct Cost
|
||||||
{ enum { value = (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost }; };
|
{ enum { value = (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost }; };
|
||||||
EIGEN_DEVICE_FUNC member_lpnorm() {}
|
EIGEN_DEVICE_FUNC member_lpnorm() {}
|
||||||
template<typename XprType>
|
template<typename XprType>
|
||||||
|
|
@ -121,17 +128,20 @@ struct member_lpnorm {
|
||||||
{ return mat.template lpNorm<p>(); }
|
{ return mat.template lpNorm<p>(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename BinaryOp, typename Scalar>
|
template <typename BinaryOpT, typename Scalar>
|
||||||
struct member_redux {
|
struct member_redux {
|
||||||
|
typedef BinaryOpT BinaryOp;
|
||||||
typedef typename result_of<
|
typedef typename result_of<
|
||||||
BinaryOp(const Scalar&,const Scalar&)
|
BinaryOp(const Scalar&,const Scalar&)
|
||||||
>::type result_type;
|
>::type result_type;
|
||||||
template<typename _Scalar, int Size> struct Cost
|
|
||||||
{ enum { value = (Size-1) * functor_traits<BinaryOp>::Cost }; };
|
enum { Vectorizable = functor_traits<BinaryOp>::PacketAccess };
|
||||||
|
template<int Size> struct Cost { enum { value = (Size-1) * functor_traits<BinaryOp>::Cost }; };
|
||||||
EIGEN_DEVICE_FUNC explicit member_redux(const BinaryOp func) : m_functor(func) {}
|
EIGEN_DEVICE_FUNC explicit member_redux(const BinaryOp func) : m_functor(func) {}
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_DEVICE_FUNC inline result_type operator()(const DenseBase<Derived>& mat) const
|
EIGEN_DEVICE_FUNC inline result_type operator()(const DenseBase<Derived>& mat) const
|
||||||
{ return mat.redux(m_functor); }
|
{ return mat.redux(m_functor); }
|
||||||
|
const BinaryOp& binaryFunc() const { return m_functor; }
|
||||||
const BinaryOp m_functor;
|
const BinaryOp m_functor;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -139,18 +149,38 @@ struct member_redux {
|
||||||
/** \class VectorwiseOp
|
/** \class VectorwiseOp
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
*
|
*
|
||||||
* \brief Pseudo expression providing partial reduction operations
|
* \brief Pseudo expression providing broadcasting and partial reduction operations
|
||||||
*
|
*
|
||||||
* \tparam ExpressionType the type of the object on which to do partial reductions
|
* \tparam ExpressionType the type of the object on which to do partial reductions
|
||||||
* \tparam Direction indicates the direction of the redux (#Vertical or #Horizontal)
|
* \tparam Direction indicates whether to operate on columns (#Vertical) or rows (#Horizontal)
|
||||||
*
|
*
|
||||||
* This class represents a pseudo expression with partial reduction features.
|
* This class represents a pseudo expression with broadcasting and partial reduction features.
|
||||||
* It is the return type of DenseBase::colwise() and DenseBase::rowwise()
|
* It is the return type of DenseBase::colwise() and DenseBase::rowwise()
|
||||||
* and most of the time this is the only way it is used.
|
* and most of the time this is the only way it is explicitly used.
|
||||||
|
*
|
||||||
|
* To understand the logic of rowwise/colwise expression, let's consider a generic case `A.colwise().foo()`
|
||||||
|
* where `foo` is any method of `VectorwiseOp`. This expression is equivalent to applying `foo()` to each
|
||||||
|
* column of `A` and then re-assemble the outputs in a matrix expression:
|
||||||
|
* \code [A.col(0).foo(), A.col(1).foo(), ..., A.col(A.cols()-1).foo()] \endcode
|
||||||
*
|
*
|
||||||
* Example: \include MatrixBase_colwise.cpp
|
* Example: \include MatrixBase_colwise.cpp
|
||||||
* Output: \verbinclude MatrixBase_colwise.out
|
* Output: \verbinclude MatrixBase_colwise.out
|
||||||
*
|
*
|
||||||
|
* The begin() and end() methods are obviously exceptions to the previous rule as they
|
||||||
|
* return STL-compatible begin/end iterators to the rows or columns of the nested expression.
|
||||||
|
* Typical use cases include for-range-loop and calls to STL algorithms:
|
||||||
|
*
|
||||||
|
* Example: \include MatrixBase_colwise_iterator_cxx11.cpp
|
||||||
|
* Output: \verbinclude MatrixBase_colwise_iterator_cxx11.out
|
||||||
|
*
|
||||||
|
* For a partial reduction on an empty input, some rules apply.
|
||||||
|
* For the sake of clarity, let's consider a vertical reduction:
|
||||||
|
* - If the number of columns is zero, then a 1x0 row-major vector expression is returned.
|
||||||
|
* - Otherwise, if the number of rows is zero, then
|
||||||
|
* - a row vector of zeros is returned for sum-like reductions (sum, squaredNorm, norm, etc.)
|
||||||
|
* - a row vector of ones is returned for a product reduction (e.g., <code>MatrixXd(n,0).colwise().prod()</code>)
|
||||||
|
* - an assert is triggered for all other reductions (minCoeff,maxCoeff,redux(bin_op))
|
||||||
|
*
|
||||||
* \sa DenseBase::colwise(), DenseBase::rowwise(), class PartialReduxExpr
|
* \sa DenseBase::colwise(), DenseBase::rowwise(), class PartialReduxExpr
|
||||||
*/
|
*/
|
||||||
template<typename ExpressionType, int Direction> class VectorwiseOp
|
template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||||
|
|
@ -163,11 +193,11 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||||
typedef typename internal::ref_selector<ExpressionType>::non_const_type ExpressionTypeNested;
|
typedef typename internal::ref_selector<ExpressionType>::non_const_type ExpressionTypeNested;
|
||||||
typedef typename internal::remove_all<ExpressionTypeNested>::type ExpressionTypeNestedCleaned;
|
typedef typename internal::remove_all<ExpressionTypeNested>::type ExpressionTypeNestedCleaned;
|
||||||
|
|
||||||
template<template<typename _Scalar> class Functor,
|
template<template<typename OutScalar,typename InputScalar> class Functor,
|
||||||
typename Scalar_=Scalar> struct ReturnType
|
typename ReturnScalar=Scalar> struct ReturnType
|
||||||
{
|
{
|
||||||
typedef PartialReduxExpr<ExpressionType,
|
typedef PartialReduxExpr<ExpressionType,
|
||||||
Functor<Scalar_>,
|
Functor<ReturnScalar,Scalar>,
|
||||||
Direction
|
Direction
|
||||||
> Type;
|
> Type;
|
||||||
};
|
};
|
||||||
|
|
@ -187,23 +217,6 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
typedef typename internal::conditional<isVertical,
|
|
||||||
typename ExpressionType::ColXpr,
|
|
||||||
typename ExpressionType::RowXpr>::type SubVector;
|
|
||||||
/** \internal
|
|
||||||
* \returns the i-th subvector according to the \c Direction */
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
SubVector subVector(Index i)
|
|
||||||
{
|
|
||||||
return SubVector(m_matrix.derived(),i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal
|
|
||||||
* \returns the number of subvectors in the direction \c Direction */
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
Index subVectors() const
|
|
||||||
{ return isVertical?m_matrix.cols():m_matrix.rows(); }
|
|
||||||
|
|
||||||
template<typename OtherDerived> struct ExtendedType {
|
template<typename OtherDerived> struct ExtendedType {
|
||||||
typedef Replicate<OtherDerived,
|
typedef Replicate<OtherDerived,
|
||||||
isVertical ? 1 : ExpressionType::RowsAtCompileTime,
|
isVertical ? 1 : ExpressionType::RowsAtCompileTime,
|
||||||
|
|
@ -258,42 +271,101 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline const ExpressionType& _expression() const { return m_matrix; }
|
inline const ExpressionType& _expression() const { return m_matrix; }
|
||||||
|
|
||||||
|
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
/** STL-like <a href="https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator">RandomAccessIterator</a>
|
||||||
|
* iterator type over the columns or rows as returned by the begin() and end() methods.
|
||||||
|
*/
|
||||||
|
random_access_iterator_type iterator;
|
||||||
|
/** This is the const version of iterator (aka read-only) */
|
||||||
|
random_access_iterator_type const_iterator;
|
||||||
|
#else
|
||||||
|
typedef internal::subvector_stl_iterator<ExpressionType, DirectionType(Direction)> iterator;
|
||||||
|
typedef internal::subvector_stl_iterator<const ExpressionType, DirectionType(Direction)> const_iterator;
|
||||||
|
typedef internal::subvector_stl_reverse_iterator<ExpressionType, DirectionType(Direction)> reverse_iterator;
|
||||||
|
typedef internal::subvector_stl_reverse_iterator<const ExpressionType, DirectionType(Direction)> const_reverse_iterator;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** returns an iterator to the first row (rowwise) or column (colwise) of the nested expression.
|
||||||
|
* \sa end(), cbegin()
|
||||||
|
*/
|
||||||
|
iterator begin() { return iterator (m_matrix, 0); }
|
||||||
|
/** const version of begin() */
|
||||||
|
const_iterator begin() const { return const_iterator(m_matrix, 0); }
|
||||||
|
/** const version of begin() */
|
||||||
|
const_iterator cbegin() const { return const_iterator(m_matrix, 0); }
|
||||||
|
|
||||||
|
/** returns a reverse iterator to the last row (rowwise) or column (colwise) of the nested expression.
|
||||||
|
* \sa rend(), crbegin()
|
||||||
|
*/
|
||||||
|
reverse_iterator rbegin() { return reverse_iterator (m_matrix, m_matrix.template subVectors<DirectionType(Direction)>()-1); }
|
||||||
|
/** const version of rbegin() */
|
||||||
|
const_reverse_iterator rbegin() const { return const_reverse_iterator (m_matrix, m_matrix.template subVectors<DirectionType(Direction)>()-1); }
|
||||||
|
/** const version of rbegin() */
|
||||||
|
const_reverse_iterator crbegin() const { return const_reverse_iterator (m_matrix, m_matrix.template subVectors<DirectionType(Direction)>()-1); }
|
||||||
|
|
||||||
|
/** returns an iterator to the row (resp. column) following the last row (resp. column) of the nested expression
|
||||||
|
* \sa begin(), cend()
|
||||||
|
*/
|
||||||
|
iterator end() { return iterator (m_matrix, m_matrix.template subVectors<DirectionType(Direction)>()); }
|
||||||
|
/** const version of end() */
|
||||||
|
const_iterator end() const { return const_iterator(m_matrix, m_matrix.template subVectors<DirectionType(Direction)>()); }
|
||||||
|
/** const version of end() */
|
||||||
|
const_iterator cend() const { return const_iterator(m_matrix, m_matrix.template subVectors<DirectionType(Direction)>()); }
|
||||||
|
|
||||||
|
/** returns a reverse iterator to the row (resp. column) before the first row (resp. column) of the nested expression
|
||||||
|
* \sa begin(), cend()
|
||||||
|
*/
|
||||||
|
reverse_iterator rend() { return reverse_iterator (m_matrix, -1); }
|
||||||
|
/** const version of rend() */
|
||||||
|
const_reverse_iterator rend() const { return const_reverse_iterator (m_matrix, -1); }
|
||||||
|
/** const version of rend() */
|
||||||
|
const_reverse_iterator crend() const { return const_reverse_iterator (m_matrix, -1); }
|
||||||
|
|
||||||
/** \returns a row or column vector expression of \c *this reduxed by \a func
|
/** \returns a row or column vector expression of \c *this reduxed by \a func
|
||||||
*
|
*
|
||||||
* The template parameter \a BinaryOp is the type of the functor
|
* The template parameter \a BinaryOp is the type of the functor
|
||||||
* of the custom redux operator. Note that func must be an associative operator.
|
* of the custom redux operator. Note that func must be an associative operator.
|
||||||
*
|
*
|
||||||
|
* \warning the size along the reduction direction must be strictly positive,
|
||||||
|
* otherwise an assertion is triggered.
|
||||||
|
*
|
||||||
* \sa class VectorwiseOp, DenseBase::colwise(), DenseBase::rowwise()
|
* \sa class VectorwiseOp, DenseBase::colwise(), DenseBase::rowwise()
|
||||||
*/
|
*/
|
||||||
template<typename BinaryOp>
|
template<typename BinaryOp>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const typename ReduxReturnType<BinaryOp>::Type
|
const typename ReduxReturnType<BinaryOp>::Type
|
||||||
redux(const BinaryOp& func = BinaryOp()) const
|
redux(const BinaryOp& func = BinaryOp()) const
|
||||||
{ return typename ReduxReturnType<BinaryOp>::Type(_expression(), internal::member_redux<BinaryOp,Scalar>(func)); }
|
{
|
||||||
|
eigen_assert(redux_length()>0 && "you are using an empty matrix");
|
||||||
|
return typename ReduxReturnType<BinaryOp>::Type(_expression(), internal::member_redux<BinaryOp,Scalar>(func));
|
||||||
|
}
|
||||||
|
|
||||||
typedef typename ReturnType<internal::member_minCoeff>::Type MinCoeffReturnType;
|
typedef typename ReturnType<internal::member_minCoeff>::Type MinCoeffReturnType;
|
||||||
typedef typename ReturnType<internal::member_maxCoeff>::Type MaxCoeffReturnType;
|
typedef typename ReturnType<internal::member_maxCoeff>::Type MaxCoeffReturnType;
|
||||||
typedef typename ReturnType<internal::member_squaredNorm,RealScalar>::Type SquaredNormReturnType;
|
typedef PartialReduxExpr<const CwiseUnaryOp<internal::scalar_abs2_op<Scalar>, const ExpressionTypeNestedCleaned>,internal::member_sum<RealScalar,RealScalar>,Direction> SquaredNormReturnType;
|
||||||
typedef typename ReturnType<internal::member_norm,RealScalar>::Type NormReturnType;
|
typedef CwiseUnaryOp<internal::scalar_sqrt_op<RealScalar>, const SquaredNormReturnType> NormReturnType;
|
||||||
typedef typename ReturnType<internal::member_blueNorm,RealScalar>::Type BlueNormReturnType;
|
typedef typename ReturnType<internal::member_blueNorm,RealScalar>::Type BlueNormReturnType;
|
||||||
typedef typename ReturnType<internal::member_stableNorm,RealScalar>::Type StableNormReturnType;
|
typedef typename ReturnType<internal::member_stableNorm,RealScalar>::Type StableNormReturnType;
|
||||||
typedef typename ReturnType<internal::member_hypotNorm,RealScalar>::Type HypotNormReturnType;
|
typedef typename ReturnType<internal::member_hypotNorm,RealScalar>::Type HypotNormReturnType;
|
||||||
typedef typename ReturnType<internal::member_sum>::Type SumReturnType;
|
typedef typename ReturnType<internal::member_sum>::Type SumReturnType;
|
||||||
typedef typename ReturnType<internal::member_mean>::Type MeanReturnType;
|
typedef EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(SumReturnType,Scalar,quotient) MeanReturnType;
|
||||||
typedef typename ReturnType<internal::member_all>::Type AllReturnType;
|
typedef typename ReturnType<internal::member_all>::Type AllReturnType;
|
||||||
typedef typename ReturnType<internal::member_any>::Type AnyReturnType;
|
typedef typename ReturnType<internal::member_any>::Type AnyReturnType;
|
||||||
typedef PartialReduxExpr<ExpressionType, internal::member_count<Index>, Direction> CountReturnType;
|
typedef PartialReduxExpr<ExpressionType, internal::member_count<Index,Scalar>, Direction> CountReturnType;
|
||||||
typedef typename ReturnType<internal::member_prod>::Type ProdReturnType;
|
typedef typename ReturnType<internal::member_prod>::Type ProdReturnType;
|
||||||
typedef Reverse<const ExpressionType, Direction> ConstReverseReturnType;
|
typedef Reverse<const ExpressionType, Direction> ConstReverseReturnType;
|
||||||
typedef Reverse<ExpressionType, Direction> ReverseReturnType;
|
typedef Reverse<ExpressionType, Direction> ReverseReturnType;
|
||||||
|
|
||||||
template<int p> struct LpNormReturnType {
|
template<int p> struct LpNormReturnType {
|
||||||
typedef PartialReduxExpr<ExpressionType, internal::member_lpnorm<p,RealScalar>,Direction> Type;
|
typedef PartialReduxExpr<ExpressionType, internal::member_lpnorm<p,RealScalar,Scalar>,Direction> Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \returns a row (or column) vector expression of the smallest coefficient
|
/** \returns a row (or column) vector expression of the smallest coefficient
|
||||||
* of each column (or row) of the referenced expression.
|
* of each column (or row) of the referenced expression.
|
||||||
*
|
*
|
||||||
|
* \warning the size along the reduction direction must be strictly positive,
|
||||||
|
* otherwise an assertion is triggered.
|
||||||
|
*
|
||||||
* \warning the result is undefined if \c *this contains NaN.
|
* \warning the result is undefined if \c *this contains NaN.
|
||||||
*
|
*
|
||||||
* Example: \include PartialRedux_minCoeff.cpp
|
* Example: \include PartialRedux_minCoeff.cpp
|
||||||
|
|
@ -302,11 +374,17 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||||
* \sa DenseBase::minCoeff() */
|
* \sa DenseBase::minCoeff() */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const MinCoeffReturnType minCoeff() const
|
const MinCoeffReturnType minCoeff() const
|
||||||
{ return MinCoeffReturnType(_expression()); }
|
{
|
||||||
|
eigen_assert(redux_length()>0 && "you are using an empty matrix");
|
||||||
|
return MinCoeffReturnType(_expression());
|
||||||
|
}
|
||||||
|
|
||||||
/** \returns a row (or column) vector expression of the largest coefficient
|
/** \returns a row (or column) vector expression of the largest coefficient
|
||||||
* of each column (or row) of the referenced expression.
|
* of each column (or row) of the referenced expression.
|
||||||
*
|
*
|
||||||
|
* \warning the size along the reduction direction must be strictly positive,
|
||||||
|
* otherwise an assertion is triggered.
|
||||||
|
*
|
||||||
* \warning the result is undefined if \c *this contains NaN.
|
* \warning the result is undefined if \c *this contains NaN.
|
||||||
*
|
*
|
||||||
* Example: \include PartialRedux_maxCoeff.cpp
|
* Example: \include PartialRedux_maxCoeff.cpp
|
||||||
|
|
@ -315,7 +393,10 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||||
* \sa DenseBase::maxCoeff() */
|
* \sa DenseBase::maxCoeff() */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const MaxCoeffReturnType maxCoeff() const
|
const MaxCoeffReturnType maxCoeff() const
|
||||||
{ return MaxCoeffReturnType(_expression()); }
|
{
|
||||||
|
eigen_assert(redux_length()>0 && "you are using an empty matrix");
|
||||||
|
return MaxCoeffReturnType(_expression());
|
||||||
|
}
|
||||||
|
|
||||||
/** \returns a row (or column) vector expression of the squared norm
|
/** \returns a row (or column) vector expression of the squared norm
|
||||||
* of each column (or row) of the referenced expression.
|
* of each column (or row) of the referenced expression.
|
||||||
|
|
@ -327,7 +408,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||||
* \sa DenseBase::squaredNorm() */
|
* \sa DenseBase::squaredNorm() */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const SquaredNormReturnType squaredNorm() const
|
const SquaredNormReturnType squaredNorm() const
|
||||||
{ return SquaredNormReturnType(_expression()); }
|
{ return SquaredNormReturnType(m_matrix.cwiseAbs2()); }
|
||||||
|
|
||||||
/** \returns a row (or column) vector expression of the norm
|
/** \returns a row (or column) vector expression of the norm
|
||||||
* of each column (or row) of the referenced expression.
|
* of each column (or row) of the referenced expression.
|
||||||
|
|
@ -339,7 +420,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||||
* \sa DenseBase::norm() */
|
* \sa DenseBase::norm() */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const NormReturnType norm() const
|
const NormReturnType norm() const
|
||||||
{ return NormReturnType(_expression()); }
|
{ return NormReturnType(squaredNorm()); }
|
||||||
|
|
||||||
/** \returns a row (or column) vector expression of the norm
|
/** \returns a row (or column) vector expression of the norm
|
||||||
* of each column (or row) of the referenced expression.
|
* of each column (or row) of the referenced expression.
|
||||||
|
|
@ -404,7 +485,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||||
* \sa DenseBase::mean() */
|
* \sa DenseBase::mean() */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const MeanReturnType mean() const
|
const MeanReturnType mean() const
|
||||||
{ return MeanReturnType(_expression()); }
|
{ return sum() / Scalar(Direction==Vertical?m_matrix.rows():m_matrix.cols()); }
|
||||||
|
|
||||||
/** \returns a row (or column) vector expression representing
|
/** \returns a row (or column) vector expression representing
|
||||||
* whether \b all coefficients of each respective column (or row) are \c true.
|
* whether \b all coefficients of each respective column (or row) are \c true.
|
||||||
|
|
@ -500,7 +581,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
|
||||||
EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
|
EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
|
||||||
//eigen_assert((m_matrix.isNull()) == (other.isNull())); FIXME
|
//eigen_assert((m_matrix.isNull()) == (other.isNull())); FIXME
|
||||||
return const_cast<ExpressionType&>(m_matrix = extendedTo(other.derived()));
|
return m_matrix = extendedTo(other.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds the vector \a other to each subvector of \c *this */
|
/** Adds the vector \a other to each subvector of \c *this */
|
||||||
|
|
@ -510,7 +591,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
|
||||||
EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
|
EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
|
||||||
return const_cast<ExpressionType&>(m_matrix += extendedTo(other.derived()));
|
return m_matrix += extendedTo(other.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Substracts the vector \a other to each subvector of \c *this */
|
/** Substracts the vector \a other to each subvector of \c *this */
|
||||||
|
|
@ -520,7 +601,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
|
||||||
EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
|
EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
|
||||||
return const_cast<ExpressionType&>(m_matrix -= extendedTo(other.derived()));
|
return m_matrix -= extendedTo(other.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Multiples each subvector of \c *this by the vector \a other */
|
/** Multiples each subvector of \c *this by the vector \a other */
|
||||||
|
|
@ -532,7 +613,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||||
EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
|
EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
|
||||||
EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
|
EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
|
||||||
m_matrix *= extendedTo(other.derived());
|
m_matrix *= extendedTo(other.derived());
|
||||||
return const_cast<ExpressionType&>(m_matrix);
|
return m_matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Divides each subvector of \c *this by the vector \a other */
|
/** Divides each subvector of \c *this by the vector \a other */
|
||||||
|
|
@ -544,7 +625,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||||
EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
|
EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
|
||||||
EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
|
EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
|
||||||
m_matrix /= extendedTo(other.derived());
|
m_matrix /= extendedTo(other.derived());
|
||||||
return const_cast<ExpressionType&>(m_matrix);
|
return m_matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the expression of the sum of the vector \a other to each subvector of \c *this */
|
/** Returns the expression of the sum of the vector \a other to each subvector of \c *this */
|
||||||
|
|
@ -609,7 +690,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
CwiseBinaryOp<internal::scalar_quotient_op<Scalar>,
|
CwiseBinaryOp<internal::scalar_quotient_op<Scalar>,
|
||||||
const ExpressionTypeNestedCleaned,
|
const ExpressionTypeNestedCleaned,
|
||||||
const typename OppositeExtendedType<typename ReturnType<internal::member_norm,RealScalar>::Type>::Type>
|
const typename OppositeExtendedType<NormReturnType>::Type>
|
||||||
normalized() const { return m_matrix.cwiseQuotient(extendedToOpposite(this->norm())); }
|
normalized() const { return m_matrix.cwiseQuotient(extendedToOpposite(this->norm())); }
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -658,7 +739,15 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const HNormalizedReturnType hnormalized() const;
|
const HNormalizedReturnType hnormalized() const;
|
||||||
|
|
||||||
|
# ifdef EIGEN_VECTORWISEOP_PLUGIN
|
||||||
|
# include EIGEN_VECTORWISEOP_PLUGIN
|
||||||
|
# endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
Index redux_length() const
|
||||||
|
{
|
||||||
|
return Direction==Vertical ? m_matrix.rows() : m_matrix.cols();
|
||||||
|
}
|
||||||
ExpressionTypeNested m_matrix;
|
ExpressionTypeNested m_matrix;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -670,7 +759,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||||
* \sa rowwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting
|
* \sa rowwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline typename DenseBase<Derived>::ColwiseReturnType
|
EIGEN_DEVICE_FUNC inline typename DenseBase<Derived>::ColwiseReturnType
|
||||||
DenseBase<Derived>::colwise()
|
DenseBase<Derived>::colwise()
|
||||||
{
|
{
|
||||||
return ColwiseReturnType(derived());
|
return ColwiseReturnType(derived());
|
||||||
|
|
@ -684,7 +773,7 @@ DenseBase<Derived>::colwise()
|
||||||
* \sa colwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting
|
* \sa colwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline typename DenseBase<Derived>::RowwiseReturnType
|
EIGEN_DEVICE_FUNC inline typename DenseBase<Derived>::RowwiseReturnType
|
||||||
DenseBase<Derived>::rowwise()
|
DenseBase<Derived>::rowwise()
|
||||||
{
|
{
|
||||||
return RowwiseReturnType(derived());
|
return RowwiseReturnType(derived());
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue