mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Compare commits
119 Commits
3.4.0-rc1
...
starting_n
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09f3e95447 | ||
|
|
6533187280 | ||
|
|
029f78abf0 | ||
|
|
5d47f6697d | ||
|
|
ad67705447 | ||
|
|
9fc17867e5 | ||
|
|
3999ab2dc7 | ||
|
|
58db05afbc | ||
|
|
bfadb56107 | ||
|
|
9b8cdceea8 | ||
|
|
a8ec6d6a36 | ||
|
|
54f80f442d | ||
|
|
70c0363c28 | ||
|
|
b2cd094863 | ||
|
|
d216764f46 | ||
|
|
646d92c7f1 | ||
|
|
c62ed9b214 | ||
|
|
82a7715b01 | ||
|
|
43ce8e9d2d | ||
|
|
ca0d3f92d7 | ||
|
|
5bffe09624 | ||
|
|
421891e1db | ||
|
|
f826663a3a | ||
|
|
b5a926a0f6 | ||
|
|
78ee3d6261 | ||
|
|
af1247fbc1 | ||
|
|
87729ea39f | ||
|
|
748489ef9c | ||
|
|
d59ef212e1 | ||
|
|
e7b8643d70 | ||
|
|
5521c65afb | ||
|
|
69a4f70956 | ||
|
|
824272cde8 | ||
|
|
4811e81966 | ||
|
|
f019b97aca | ||
|
|
0cc9b5eb40 | ||
|
|
c3fbc6cec7 | ||
|
|
ed964ba3f1 | ||
|
|
8dfe1029a5 | ||
|
|
eb71e5db98 | ||
|
|
df4bc2731c | ||
|
|
75ce9cd2a7 | ||
|
|
9fb7062440 | ||
|
|
b8502a9dd6 | ||
|
|
2e83cbbba9 | ||
|
|
c0a889890f | ||
|
|
f612df2736 | ||
|
|
14b7ebea11 | ||
|
|
c9d4367fa4 | ||
|
|
d24f9f9b55 | ||
|
|
14487ed14e | ||
|
|
b271110788 | ||
|
|
d098c4d64c | ||
|
|
543e34ab9d | ||
|
|
b8d1857f0d | ||
|
|
853a5c4b84 | ||
|
|
94327dbfba | ||
|
|
1296abdf82 | ||
|
|
6045243141 | ||
|
|
1a96d49afe | ||
|
|
2468253c9a | ||
|
|
82d61af3a4 | ||
|
|
5f0b4a4010 | ||
|
|
6cbb3038ac | ||
|
|
5bfc67f9e7 | ||
|
|
a6601070f2 | ||
|
|
9a663973b4 | ||
|
|
e72dfeb8b9 | ||
|
|
199c5f2b47 | ||
|
|
1e0c7d4f49 | ||
|
|
976ae0ca6f | ||
|
|
c65c2b31d4 | ||
|
|
39a590dfb6 | ||
|
|
8f686ac4ec | ||
|
|
2660d01fa7 | ||
|
|
a3521d743c | ||
|
|
ca528593f4 | ||
|
|
81b5fe2f0a | ||
|
|
4fb3459a23 | ||
|
|
4bfcee47b9 | ||
|
|
29ebd84cb7 | ||
|
|
fe19714f80 | ||
|
|
e67672024d | ||
|
|
5e7d4c33d6 | ||
|
|
fb5b59641a | ||
|
|
e19829c3b0 | ||
|
|
5529db7524 | ||
|
|
51eba8c3e2 | ||
|
|
5297b7162a | ||
|
|
ecb7b19dfa | ||
|
|
6eebe97bab | ||
|
|
f284c8592b | ||
|
|
4cb0592af7 | ||
|
|
6b34568c74 | ||
|
|
0065f9d322 | ||
|
|
841c8986f8 | ||
|
|
113e61f364 | ||
|
|
98ca58b02c | ||
|
|
c31ead8a15 | ||
|
|
f44197fabd | ||
|
|
a31effc3bc | ||
|
|
8523d447a1 | ||
|
|
5908aeeaba | ||
|
|
119763cf38 | ||
|
|
6cf0ab5e99 | ||
|
|
aba3998278 | ||
|
|
db5691ff2b | ||
|
|
88d4c6d4c8 | ||
|
|
2ac0b78739 | ||
|
|
10c77b0ff4 | ||
|
|
73922b0174 | ||
|
|
5f9cfb2529 | ||
|
|
ce4af0b38f | ||
|
|
a7749c09bc | ||
|
|
128eebf05e | ||
|
|
33e0af0130 | ||
|
|
7f09d3487d | ||
|
|
12fd3dd655 | ||
|
|
aa8b22e776 |
69
.gitlab/issue_templates/Bug Report.md
Normal file
69
.gitlab/issue_templates/Bug Report.md
Normal file
@@ -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.
|
||||
7
.gitlab/issue_templates/Feature Request.md
Normal file
7
.gitlab/issue_templates/Feature Request.md
Normal file
@@ -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
.gitlab/merge_request_templates/Merge Request Template.md
Normal file
26
.gitlab/merge_request_templates/Merge Request Template.md
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.-->
|
||||
10
Eigen/Core
10
Eigen/Core
@@ -40,6 +40,13 @@
|
||||
#pragma GCC optimize ("-fno-ipa-cp-clone")
|
||||
#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>
|
||||
|
||||
// this include file manages BLAS and MKL related macros
|
||||
@@ -343,6 +350,9 @@ using std::ptrdiff_t;
|
||||
#include "src/Core/arch/AltiVec/MatrixProduct.h"
|
||||
#elif defined EIGEN_VECTORIZE_NEON
|
||||
#include "src/Core/arch/NEON/GeneralBlockPanelKernel.h"
|
||||
#include "src/Core/arch/NEON/MatrixProduct.h"
|
||||
#include "src/Core/arch/NEON/PackingOps.h"
|
||||
#include "src/Core/arch/NEON/Kernels.h"
|
||||
#endif
|
||||
|
||||
#include "src/Core/BooleanRedux.h"
|
||||
|
||||
@@ -246,8 +246,8 @@ template<typename _MatrixType, int _UpLo> class LDLT
|
||||
*/
|
||||
const LDLT& adjoint() const { return *this; };
|
||||
|
||||
EIGEN_DEVICE_FUNC inline Index rows() const { return m_matrix.rows(); }
|
||||
EIGEN_DEVICE_FUNC inline Index cols() const { return m_matrix.cols(); }
|
||||
EIGEN_DEVICE_FUNC inline EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
|
||||
EIGEN_DEVICE_FUNC inline EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
|
||||
|
||||
/** \brief Reports whether previous computation was successful.
|
||||
*
|
||||
|
||||
@@ -199,10 +199,10 @@ template<typename _MatrixType, int _UpLo> class LLT
|
||||
* This method is provided for compatibility with other matrix decompositions, thus enabling generic code such as:
|
||||
* \code x = decomposition.adjoint().solve(b) \endcode
|
||||
*/
|
||||
const LLT& adjoint() const { return *this; };
|
||||
const LLT& adjoint() const EIGEN_NOEXCEPT { return *this; };
|
||||
|
||||
inline Index rows() const { return m_matrix.rows(); }
|
||||
inline Index cols() const { return m_matrix.cols(); }
|
||||
inline EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
|
||||
inline EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
|
||||
|
||||
template<typename VectorType>
|
||||
LLT & rankUpdate(const VectorType& vec, const RealScalar& sigma = 1);
|
||||
|
||||
@@ -117,7 +117,7 @@ class Array
|
||||
{
|
||||
return Base::_set(other);
|
||||
}
|
||||
|
||||
|
||||
/** Default constructor.
|
||||
*
|
||||
* For fixed-size matrices, does nothing.
|
||||
@@ -157,7 +157,7 @@ class Array
|
||||
EIGEN_DEVICE_FUNC
|
||||
Array& operator=(Array&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_assignable<Scalar>::value)
|
||||
{
|
||||
other.swap(*this);
|
||||
Base::operator=(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
@@ -177,24 +177,24 @@ class Array
|
||||
: 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
|
||||
@@ -241,7 +241,7 @@ class Array
|
||||
/** 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);
|
||||
#endif // end EIGEN_PARSED_BY_DOXYGEN
|
||||
#endif // end EIGEN_PARSED_BY_DOXYGEN
|
||||
|
||||
/** 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)
|
||||
@@ -288,8 +288,10 @@ class Array
|
||||
: Base(other.derived())
|
||||
{ }
|
||||
|
||||
EIGEN_DEVICE_FUNC inline Index innerStride() const { return 1; }
|
||||
EIGEN_DEVICE_FUNC inline Index outerStride() const { return this->innerSize(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
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
|
||||
#include EIGEN_ARRAY_PLUGIN
|
||||
@@ -322,7 +324,7 @@ class Array
|
||||
* 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
|
||||
*/
|
||||
|
||||
@@ -367,7 +369,7 @@ using Array##SizeSuffix##SizeSuffix = Array<Type, Size, Size>; \
|
||||
/** \ingroup arraytypedefs */ \
|
||||
/** \brief \cpp11 */ \
|
||||
template <typename Type> \
|
||||
using Array##SizeSuffix = Array<Type, Size, 1>;
|
||||
using Array##SizeSuffix = Array<Type, Size, 1>;
|
||||
|
||||
#define EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Size) \
|
||||
/** \ingroup arraytypedefs */ \
|
||||
@@ -391,7 +393,7 @@ EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(4)
|
||||
#undef EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS
|
||||
|
||||
#endif // EIGEN_HAS_CXX11
|
||||
|
||||
|
||||
#define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \
|
||||
using Eigen::Matrix##SizeSuffix##TypeSuffix; \
|
||||
using Eigen::Vector##SizeSuffix##TypeSuffix; \
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#ifndef EIGEN_ARRAYWRAPPER_H
|
||||
#define EIGEN_ARRAYWRAPPER_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
/** \class ArrayWrapper
|
||||
* \ingroup Core_Module
|
||||
@@ -60,14 +60,14 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit EIGEN_STRONG_INLINE ArrayWrapper(ExpressionType& matrix) : m_expression(matrix) {}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index rows() const { return m_expression.rows(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index cols() const { return m_expression.cols(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index outerStride() const { return m_expression.outerStride(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index innerStride() const { return m_expression.innerStride(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index rows() const EIGEN_NOEXCEPT { return m_expression.rows(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
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 ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
|
||||
@@ -91,8 +91,8 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
|
||||
inline void evalTo(Dest& dst) const { dst = m_expression; }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
const typename internal::remove_all<NestedExpressionType>::type&
|
||||
nestedExpression() const
|
||||
const typename internal::remove_all<NestedExpressionType>::type&
|
||||
nestedExpression() const
|
||||
{
|
||||
return m_expression;
|
||||
}
|
||||
@@ -158,14 +158,14 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit inline MatrixWrapper(ExpressionType& matrix) : m_expression(matrix) {}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index rows() const { return m_expression.rows(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index cols() const { return m_expression.cols(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index outerStride() const { return m_expression.outerStride(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index innerStride() const { return m_expression.innerStride(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index rows() const EIGEN_NOEXCEPT { return m_expression.rows(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
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 ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
|
||||
@@ -185,8 +185,8 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
const typename internal::remove_all<NestedExpressionType>::type&
|
||||
nestedExpression() const
|
||||
const typename internal::remove_all<NestedExpressionType>::type&
|
||||
nestedExpression() const
|
||||
{
|
||||
return m_expression;
|
||||
}
|
||||
|
||||
@@ -450,7 +450,7 @@ struct dense_assignment_loop<Kernel, LinearVectorizedTraversal, CompleteUnrollin
|
||||
|
||||
enum { size = DstXprType::SizeAtCompileTime,
|
||||
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_DefaultTraversal_CompleteUnrolling<Kernel, alignedSize, size>::run(kernel);
|
||||
@@ -638,15 +638,15 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC Index size() const { return m_dstExpr.size(); }
|
||||
EIGEN_DEVICE_FUNC Index innerSize() const { return m_dstExpr.innerSize(); }
|
||||
EIGEN_DEVICE_FUNC Index outerSize() const { return m_dstExpr.outerSize(); }
|
||||
EIGEN_DEVICE_FUNC Index rows() const { return m_dstExpr.rows(); }
|
||||
EIGEN_DEVICE_FUNC Index cols() const { return m_dstExpr.cols(); }
|
||||
EIGEN_DEVICE_FUNC Index outerStride() const { return m_dstExpr.outerStride(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index size() const EIGEN_NOEXCEPT { return m_dstExpr.size(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index innerSize() const EIGEN_NOEXCEPT { return m_dstExpr.innerSize(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index outerSize() const EIGEN_NOEXCEPT { return m_dstExpr.outerSize(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_dstExpr.rows(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_dstExpr.cols(); }
|
||||
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 const SrcEvaluatorType& srcEvaluator() const { return m_src; }
|
||||
EIGEN_DEVICE_FUNC DstEvaluatorType& dstEvaluator() EIGEN_NOEXCEPT { return m_dst; }
|
||||
EIGEN_DEVICE_FUNC const SrcEvaluatorType& srcEvaluator() const EIGEN_NOEXCEPT { return m_src; }
|
||||
|
||||
/// Assign src(row,col) to dst(row,col) through the assignment functor.
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(Index row, Index col)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#ifndef EIGEN_BANDMATRIX_H
|
||||
#define EIGEN_BANDMATRIX_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
@@ -45,7 +45,7 @@ class BandMatrixBase : public EigenBase<Derived>
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
|
||||
using Base::derived;
|
||||
using Base::rows;
|
||||
using Base::cols;
|
||||
@@ -55,10 +55,10 @@ class BandMatrixBase : public EigenBase<Derived>
|
||||
|
||||
/** \returns the number of sub diagonals */
|
||||
inline Index subs() const { return derived().subs(); }
|
||||
|
||||
|
||||
/** \returns an expression of the underlying coefficient matrix */
|
||||
inline const CoefficientsType& coeffs() const { return derived().coeffs(); }
|
||||
|
||||
|
||||
/** \returns an expression of the underlying coefficient matrix */
|
||||
inline CoefficientsType& coeffs() { return derived().coeffs(); }
|
||||
|
||||
@@ -130,7 +130,7 @@ class BandMatrixBase : public EigenBase<Derived>
|
||||
eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers()));
|
||||
return Block<const CoefficientsType,1,Dynamic>(coeffs(), supers()-i, std::max<Index>(0,i), 1, diagonalLength(i));
|
||||
}
|
||||
|
||||
|
||||
template<typename Dest> inline void evalTo(Dest& dst) const
|
||||
{
|
||||
dst.resize(rows(),cols());
|
||||
@@ -211,16 +211,16 @@ class BandMatrix : public BandMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Sub
|
||||
}
|
||||
|
||||
/** \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 */
|
||||
inline Index cols() const { return m_coeffs.cols(); }
|
||||
inline EIGEN_CONSTEXPR Index cols() const { return m_coeffs.cols(); }
|
||||
|
||||
/** \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 */
|
||||
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 CoefficientsType& coeffs() { return m_coeffs; }
|
||||
@@ -275,16 +275,16 @@ class BandMatrixWrapper : public BandMatrixBase<BandMatrixWrapper<_CoefficientsT
|
||||
}
|
||||
|
||||
/** \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 */
|
||||
inline Index cols() const { return m_coeffs.cols(); }
|
||||
inline EIGEN_CONSTEXPR Index cols() const { return m_coeffs.cols(); }
|
||||
|
||||
/** \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 */
|
||||
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; }
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#ifndef EIGEN_BLOCK_H
|
||||
#define EIGEN_BLOCK_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
|
||||
@@ -52,7 +52,7 @@ struct traits<Block<XprType, BlockRows, BlockCols, InnerPanel> > : traits<XprTyp
|
||||
FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
|
||||
Flags = (traits<XprType>::Flags & (DirectAccessBit | (InnerPanel?CompressedAccessBit:0))) | FlagsLvalueBit | FlagsRowMajorBit,
|
||||
// FIXME DirectAccessBit should not be handled by expressions
|
||||
//
|
||||
//
|
||||
// Alignment is needed by MapBase's assertions
|
||||
// We can sefely set it to false here. Internal alignment errors will be detected by an eigen_internal_assert in the respective evaluator
|
||||
Alignment = 0
|
||||
@@ -61,7 +61,7 @@ struct traits<Block<XprType, BlockRows, BlockCols, InnerPanel> > : traits<XprTyp
|
||||
|
||||
template<typename XprType, int BlockRows=Dynamic, int BlockCols=Dynamic, bool InnerPanel = false,
|
||||
bool HasDirectAccess = internal::has_direct_access<XprType>::ret> class BlockImpl_dense;
|
||||
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, typename StorageKind> class BlockImpl;
|
||||
@@ -109,9 +109,9 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> class
|
||||
typedef Impl Base;
|
||||
EIGEN_GENERIC_PUBLIC_INTERFACE(Block)
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
|
||||
|
||||
|
||||
typedef typename internal::remove_all<XprType>::type NestedExpression;
|
||||
|
||||
|
||||
/** Column or Row constructor
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
@@ -147,7 +147,7 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> class
|
||||
&& startCol >= 0 && blockCols >= 0 && startCol <= xpr.cols() - blockCols);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// The generic default implementation for dense block simplu forward to the internal::BlockImpl_dense
|
||||
// that must be specialized for direct and non-direct access...
|
||||
template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
|
||||
@@ -296,23 +296,23 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool H
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
const typename internal::remove_all<XprTypeNested>::type& nestedExpression() const
|
||||
{
|
||||
return m_xpr;
|
||||
{
|
||||
return m_xpr;
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
XprType& nestedExpression() { return m_xpr; }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
StorageIndex startRow() const
|
||||
{
|
||||
return m_startRow.value();
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
StorageIndex startRow() const EIGEN_NOEXCEPT
|
||||
{
|
||||
return m_startRow.value();
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
StorageIndex startCol() const
|
||||
{
|
||||
return m_startCol.value();
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
StorageIndex startCol() const EIGEN_NOEXCEPT
|
||||
{
|
||||
return m_startCol.value();
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -344,7 +344,7 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
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==1 ? 1 : xpr.rows(),
|
||||
BlockCols==1 ? 1 : xpr.cols()),
|
||||
@@ -378,17 +378,17 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
const typename internal::remove_all<XprTypeNested>::type& nestedExpression() const
|
||||
{
|
||||
return m_xpr;
|
||||
const typename internal::remove_all<XprTypeNested>::type& nestedExpression() const EIGEN_NOEXCEPT
|
||||
{
|
||||
return m_xpr;
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
XprType& nestedExpression() { return m_xpr; }
|
||||
|
||||
|
||||
/** \sa MapBase::innerStride() */
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
Index innerStride() const
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
Index innerStride() const EIGEN_NOEXCEPT
|
||||
{
|
||||
return internal::traits<BlockType>::HasSameStorageOrderAsXprType
|
||||
? m_xpr.innerStride()
|
||||
@@ -396,23 +396,19 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
||||
}
|
||||
|
||||
/** \sa MapBase::outerStride() */
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
Index outerStride() const
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
Index outerStride() const EIGEN_NOEXCEPT
|
||||
{
|
||||
return m_outerStride;
|
||||
return internal::traits<BlockType>::HasSameStorageOrderAsXprType
|
||||
? m_xpr.outerStride()
|
||||
: m_xpr.innerStride();
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
StorageIndex startRow() const
|
||||
{
|
||||
return m_startRow.value();
|
||||
}
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
StorageIndex startRow() const EIGEN_NOEXCEPT { return m_startRow.value(); }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
StorageIndex startCol() const
|
||||
{
|
||||
return m_startCol.value();
|
||||
}
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
StorageIndex startCol() const EIGEN_NOEXCEPT { return m_startCol.value(); }
|
||||
|
||||
#ifndef __SUNPRO_CC
|
||||
// FIXME sunstudio is not friendly with the above friend...
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#define EIGEN_COREEVALUATORS_H
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
|
||||
namespace internal {
|
||||
|
||||
// This class returns the evaluator kind from the expression storage kind.
|
||||
@@ -63,8 +63,8 @@ template< typename T,
|
||||
template< typename T,
|
||||
typename Kind = typename evaluator_traits<typename T::NestedExpression>::Kind,
|
||||
typename Scalar = typename T::Scalar> struct unary_evaluator;
|
||||
|
||||
// evaluator_traits<T> contains traits for evaluator<T>
|
||||
|
||||
// evaluator_traits<T> contains traits for evaluator<T>
|
||||
|
||||
template<typename T>
|
||||
struct evaluator_traits_base
|
||||
@@ -111,7 +111,7 @@ 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.
|
||||
typedef traits<ExpressionType> ExpressionTraits;
|
||||
|
||||
|
||||
enum {
|
||||
Alignment = 0
|
||||
};
|
||||
@@ -143,8 +143,8 @@ public:
|
||||
#endif
|
||||
eigen_internal_assert(outerStride==OuterStride);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
Index outerStride() const { return OuterStride; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
Index outerStride() const EIGEN_NOEXCEPT { return OuterStride; }
|
||||
const Scalar *data;
|
||||
};
|
||||
|
||||
@@ -172,7 +172,7 @@ struct evaluator<PlainObjectBase<Derived> >
|
||||
IsVectorAtCompileTime = PlainObjectType::IsVectorAtCompileTime,
|
||||
RowsAtCompileTime = PlainObjectType::RowsAtCompileTime,
|
||||
ColsAtCompileTime = PlainObjectType::ColsAtCompileTime,
|
||||
|
||||
|
||||
CoeffReadCost = NumTraits<Scalar>::ReadCost,
|
||||
Flags = traits<Derived>::EvaluatorFlags,
|
||||
Alignment = traits<Derived>::Alignment
|
||||
@@ -274,13 +274,13 @@ struct evaluator<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
|
||||
: evaluator<PlainObjectBase<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> > >
|
||||
{
|
||||
typedef Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> XprType;
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
evaluator() {}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
explicit evaluator(const XprType& m)
|
||||
: evaluator<PlainObjectBase<XprType> >(m)
|
||||
: evaluator<PlainObjectBase<XprType> >(m)
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -292,10 +292,10 @@ struct evaluator<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
evaluator() {}
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
explicit evaluator(const XprType& m)
|
||||
: evaluator<PlainObjectBase<XprType> >(m)
|
||||
: evaluator<PlainObjectBase<XprType> >(m)
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -306,9 +306,9 @@ struct unary_evaluator<Transpose<ArgType>, IndexBased>
|
||||
: evaluator_base<Transpose<ArgType> >
|
||||
{
|
||||
typedef Transpose<ArgType> XprType;
|
||||
|
||||
|
||||
enum {
|
||||
CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
|
||||
CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
|
||||
Flags = evaluator<ArgType>::Flags ^ RowMajorBit,
|
||||
Alignment = evaluator<ArgType>::Alignment
|
||||
};
|
||||
@@ -499,10 +499,10 @@ struct evaluator<CwiseNullaryOp<NullaryOp,PlainObjectType> >
|
||||
{
|
||||
typedef CwiseNullaryOp<NullaryOp,PlainObjectType> XprType;
|
||||
typedef typename internal::remove_all<PlainObjectType>::type PlainObjectTypeCleaned;
|
||||
|
||||
|
||||
enum {
|
||||
CoeffReadCost = internal::functor_traits<NullaryOp>::Cost,
|
||||
|
||||
|
||||
Flags = (evaluator<PlainObjectTypeCleaned>::Flags
|
||||
& ( HereditaryBits
|
||||
| (functor_has_linear_access<NullaryOp>::ret ? LinearAccessBit : 0)
|
||||
@@ -559,10 +559,10 @@ struct unary_evaluator<CwiseUnaryOp<UnaryOp, ArgType>, IndexBased >
|
||||
: evaluator_base<CwiseUnaryOp<UnaryOp, ArgType> >
|
||||
{
|
||||
typedef CwiseUnaryOp<UnaryOp, ArgType> XprType;
|
||||
|
||||
|
||||
enum {
|
||||
CoeffReadCost = evaluator<ArgType>::CoeffReadCost + functor_traits<UnaryOp>::Cost,
|
||||
|
||||
|
||||
Flags = evaluator<ArgType>::Flags
|
||||
& (HereditaryBits | LinearAccessBit | (functor_traits<UnaryOp>::PacketAccess ? PacketAccessBit : 0)),
|
||||
Alignment = evaluator<ArgType>::Alignment
|
||||
@@ -628,7 +628,7 @@ struct evaluator<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> >
|
||||
{
|
||||
typedef CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> XprType;
|
||||
typedef ternary_evaluator<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> > Base;
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr) : Base(xpr) {}
|
||||
};
|
||||
|
||||
@@ -637,10 +637,10 @@ struct ternary_evaluator<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>, IndexBased
|
||||
: evaluator_base<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> >
|
||||
{
|
||||
typedef CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> XprType;
|
||||
|
||||
|
||||
enum {
|
||||
CoeffReadCost = evaluator<Arg1>::CoeffReadCost + evaluator<Arg2>::CoeffReadCost + evaluator<Arg3>::CoeffReadCost + functor_traits<TernaryOp>::Cost,
|
||||
|
||||
|
||||
Arg1Flags = evaluator<Arg1>::Flags,
|
||||
Arg2Flags = evaluator<Arg2>::Flags,
|
||||
Arg3Flags = evaluator<Arg3>::Flags,
|
||||
@@ -723,7 +723,7 @@ struct evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
|
||||
{
|
||||
typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
|
||||
typedef binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > Base;
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
explicit evaluator(const XprType& xpr) : Base(xpr) {}
|
||||
};
|
||||
@@ -733,10 +733,10 @@ struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>, IndexBased, IndexBase
|
||||
: evaluator_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
|
||||
{
|
||||
typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
|
||||
|
||||
|
||||
enum {
|
||||
CoeffReadCost = evaluator<Lhs>::CoeffReadCost + evaluator<Rhs>::CoeffReadCost + functor_traits<BinaryOp>::Cost,
|
||||
|
||||
|
||||
LhsFlags = evaluator<Lhs>::Flags,
|
||||
RhsFlags = evaluator<Rhs>::Flags,
|
||||
SameType = is_same<typename Lhs::Scalar,typename Rhs::Scalar>::value,
|
||||
@@ -813,12 +813,12 @@ struct unary_evaluator<CwiseUnaryView<UnaryOp, ArgType>, IndexBased>
|
||||
: evaluator_base<CwiseUnaryView<UnaryOp, ArgType> >
|
||||
{
|
||||
typedef CwiseUnaryView<UnaryOp, ArgType> XprType;
|
||||
|
||||
|
||||
enum {
|
||||
CoeffReadCost = evaluator<ArgType>::CoeffReadCost + functor_traits<UnaryOp>::Cost,
|
||||
|
||||
|
||||
Flags = (evaluator<ArgType>::Flags & (HereditaryBits | LinearAccessBit | DirectAccessBit)),
|
||||
|
||||
|
||||
Alignment = 0 // FIXME it is not very clear why alignment is necessarily lost...
|
||||
};
|
||||
|
||||
@@ -884,7 +884,7 @@ struct mapbase_evaluator : evaluator_base<Derived>
|
||||
typedef typename XprType::PointerType PointerType;
|
||||
typedef typename XprType::Scalar Scalar;
|
||||
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
||||
|
||||
|
||||
enum {
|
||||
IsRowMajor = XprType::RowsAtCompileTime,
|
||||
ColsAtCompileTime = XprType::ColsAtCompileTime,
|
||||
@@ -956,17 +956,21 @@ struct mapbase_evaluator : evaluator_base<Derived>
|
||||
internal::pstoret<Scalar, PacketType, StoreMode>(m_data + index * m_innerStride.value(), x);
|
||||
}
|
||||
protected:
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
Index rowStride() const { return XprType::IsRowMajor ? m_outerStride.value() : m_innerStride.value(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
Index colStride() const { return XprType::IsRowMajor ? m_innerStride.value() : m_outerStride.value(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
Index rowStride() const EIGEN_NOEXCEPT {
|
||||
return XprType::IsRowMajor ? m_outerStride.value() : m_innerStride.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;
|
||||
const internal::variable_if_dynamic<Index, XprType::InnerStrideAtCompileTime> m_innerStride;
|
||||
const internal::variable_if_dynamic<Index, XprType::OuterStrideAtCompileTime> m_outerStride;
|
||||
};
|
||||
|
||||
template<typename PlainObjectType, int MapOptions, typename StrideType>
|
||||
template<typename PlainObjectType, int MapOptions, typename StrideType>
|
||||
struct evaluator<Map<PlainObjectType, MapOptions, StrideType> >
|
||||
: public mapbase_evaluator<Map<PlainObjectType, MapOptions, StrideType>, PlainObjectType>
|
||||
{
|
||||
@@ -974,7 +978,7 @@ struct evaluator<Map<PlainObjectType, MapOptions, StrideType> >
|
||||
typedef typename XprType::Scalar Scalar;
|
||||
// TODO: should check for smaller packet types once we can handle multi-sized packet types
|
||||
typedef typename packet_traits<Scalar>::type PacketScalar;
|
||||
|
||||
|
||||
enum {
|
||||
InnerStrideAtCompileTime = StrideType::InnerStrideAtCompileTime == 0
|
||||
? int(PlainObjectType::InnerStrideAtCompileTime)
|
||||
@@ -986,27 +990,27 @@ struct evaluator<Map<PlainObjectType, MapOptions, StrideType> >
|
||||
HasNoOuterStride = StrideType::OuterStrideAtCompileTime == 0,
|
||||
HasNoStride = HasNoInnerStride && HasNoOuterStride,
|
||||
IsDynamicSize = PlainObjectType::SizeAtCompileTime==Dynamic,
|
||||
|
||||
|
||||
PacketAccessMask = bool(HasNoInnerStride) ? ~int(0) : ~int(PacketAccessBit),
|
||||
LinearAccessMask = bool(HasNoStride) || bool(PlainObjectType::IsVectorAtCompileTime) ? ~int(0) : ~int(LinearAccessBit),
|
||||
Flags = int( evaluator<PlainObjectType>::Flags) & (LinearAccessMask&PacketAccessMask),
|
||||
|
||||
|
||||
Alignment = int(MapOptions)&int(AlignedMask)
|
||||
};
|
||||
|
||||
EIGEN_DEVICE_FUNC explicit evaluator(const XprType& map)
|
||||
: mapbase_evaluator<XprType, PlainObjectType>(map)
|
||||
: mapbase_evaluator<XprType, PlainObjectType>(map)
|
||||
{ }
|
||||
};
|
||||
|
||||
// -------------------- Ref --------------------
|
||||
|
||||
template<typename PlainObjectType, int RefOptions, typename StrideType>
|
||||
template<typename PlainObjectType, int RefOptions, typename StrideType>
|
||||
struct evaluator<Ref<PlainObjectType, RefOptions, StrideType> >
|
||||
: public mapbase_evaluator<Ref<PlainObjectType, RefOptions, StrideType>, PlainObjectType>
|
||||
{
|
||||
typedef Ref<PlainObjectType, RefOptions, StrideType> XprType;
|
||||
|
||||
|
||||
enum {
|
||||
Flags = evaluator<Map<PlainObjectType, RefOptions, StrideType> >::Flags,
|
||||
Alignment = evaluator<Map<PlainObjectType, RefOptions, StrideType> >::Alignment
|
||||
@@ -1014,7 +1018,7 @@ struct evaluator<Ref<PlainObjectType, RefOptions, StrideType> >
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
explicit evaluator(const XprType& ref)
|
||||
: mapbase_evaluator<XprType, PlainObjectType>(ref)
|
||||
: mapbase_evaluator<XprType, PlainObjectType>(ref)
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -1022,8 +1026,8 @@ struct evaluator<Ref<PlainObjectType, RefOptions, StrideType> >
|
||||
|
||||
template<typename ArgType, int BlockRows, int BlockCols, bool InnerPanel,
|
||||
bool HasDirectAccess = internal::has_direct_access<ArgType>::ret> struct block_evaluator;
|
||||
|
||||
template<typename ArgType, int BlockRows, int BlockCols, bool InnerPanel>
|
||||
|
||||
template<typename ArgType, int BlockRows, int BlockCols, bool InnerPanel>
|
||||
struct evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel> >
|
||||
: block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel>
|
||||
{
|
||||
@@ -1031,15 +1035,15 @@ struct evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel> >
|
||||
typedef typename XprType::Scalar Scalar;
|
||||
// TODO: should check for smaller packet types once we can handle multi-sized packet types
|
||||
typedef typename packet_traits<Scalar>::type PacketScalar;
|
||||
|
||||
|
||||
enum {
|
||||
CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
|
||||
|
||||
|
||||
RowsAtCompileTime = traits<XprType>::RowsAtCompileTime,
|
||||
ColsAtCompileTime = traits<XprType>::ColsAtCompileTime,
|
||||
MaxRowsAtCompileTime = traits<XprType>::MaxRowsAtCompileTime,
|
||||
MaxColsAtCompileTime = traits<XprType>::MaxColsAtCompileTime,
|
||||
|
||||
|
||||
ArgTypeIsRowMajor = (int(evaluator<ArgType>::Flags)&RowMajorBit) != 0,
|
||||
IsRowMajor = (MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1) ? 1
|
||||
: (MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1) ? 0
|
||||
@@ -1053,14 +1057,14 @@ struct evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel> >
|
||||
? int(outer_stride_at_compile_time<ArgType>::ret)
|
||||
: int(inner_stride_at_compile_time<ArgType>::ret),
|
||||
MaskPacketAccessBit = (InnerStrideAtCompileTime == 1 || HasSameStorageOrderAsArgType) ? PacketAccessBit : 0,
|
||||
|
||||
FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1 || (InnerPanel && (evaluator<ArgType>::Flags&LinearAccessBit))) ? LinearAccessBit : 0,
|
||||
|
||||
FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1 || (InnerPanel && (evaluator<ArgType>::Flags&LinearAccessBit))) ? LinearAccessBit : 0,
|
||||
FlagsRowMajorBit = XprType::Flags&RowMajorBit,
|
||||
Flags0 = evaluator<ArgType>::Flags & ( (HereditaryBits & ~RowMajorBit) |
|
||||
DirectAccessBit |
|
||||
MaskPacketAccessBit),
|
||||
Flags = Flags0 | FlagsLinearAccessBit | FlagsRowMajorBit,
|
||||
|
||||
|
||||
PacketAlignment = unpacket_traits<PacketScalar>::alignment,
|
||||
Alignment0 = (InnerPanel && (OuterStrideAtCompileTime!=Dynamic)
|
||||
&& (OuterStrideAtCompileTime!=0)
|
||||
@@ -1084,7 +1088,7 @@ struct block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel, /*HasDirectAcc
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
explicit block_evaluator(const XprType& block)
|
||||
: unary_evaluator<XprType>(block)
|
||||
: unary_evaluator<XprType>(block)
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -1096,12 +1100,12 @@ struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IndexBa
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
explicit unary_evaluator(const XprType& block)
|
||||
: m_argImpl(block.nestedExpression()),
|
||||
m_startRow(block.startRow()),
|
||||
: m_argImpl(block.nestedExpression()),
|
||||
m_startRow(block.startRow()),
|
||||
m_startCol(block.startCol()),
|
||||
m_linear_offset(ForwardLinearAccess?(ArgType::IsRowMajor ? block.startRow()*block.nestedExpression().cols() + block.startCol() : block.startCol()*block.nestedExpression().rows() + block.startRow()):0)
|
||||
{ }
|
||||
|
||||
|
||||
typedef typename XprType::Scalar Scalar;
|
||||
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
||||
|
||||
@@ -1109,13 +1113,13 @@ struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IndexBa
|
||||
RowsAtCompileTime = XprType::RowsAtCompileTime,
|
||||
ForwardLinearAccess = (InnerPanel || int(XprType::IsRowMajor)==int(ArgType::IsRowMajor)) && bool(evaluator<ArgType>::Flags&LinearAccessBit)
|
||||
};
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
CoeffReturnType coeff(Index row, Index col) const
|
||||
{
|
||||
return m_argImpl.coeff(m_startRow.value() + row, m_startCol.value() + col);
|
||||
{
|
||||
return m_argImpl.coeff(m_startRow.value() + row, m_startCol.value() + col);
|
||||
}
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
CoeffReturnType coeff(Index index) const
|
||||
{
|
||||
@@ -1124,44 +1128,44 @@ struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IndexBa
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
Scalar& coeffRef(Index row, Index col)
|
||||
{
|
||||
return m_argImpl.coeffRef(m_startRow.value() + row, m_startCol.value() + col);
|
||||
{
|
||||
return m_argImpl.coeffRef(m_startRow.value() + row, m_startCol.value() + col);
|
||||
}
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
Scalar& coeffRef(Index index)
|
||||
{
|
||||
return linear_coeffRef_impl(index, bool_constant<ForwardLinearAccess>());
|
||||
}
|
||||
|
||||
|
||||
template<int LoadMode, typename PacketType>
|
||||
EIGEN_STRONG_INLINE
|
||||
PacketType packet(Index row, Index col) const
|
||||
{
|
||||
return m_argImpl.template packet<LoadMode,PacketType>(m_startRow.value() + row, m_startCol.value() + col);
|
||||
PacketType packet(Index row, Index col) const
|
||||
{
|
||||
return m_argImpl.template packet<LoadMode,PacketType>(m_startRow.value() + row, m_startCol.value() + col);
|
||||
}
|
||||
|
||||
template<int LoadMode, typename PacketType>
|
||||
EIGEN_STRONG_INLINE
|
||||
PacketType packet(Index index) const
|
||||
{
|
||||
PacketType packet(Index index) const
|
||||
{
|
||||
if (ForwardLinearAccess)
|
||||
return m_argImpl.template packet<LoadMode,PacketType>(m_linear_offset.value() + index);
|
||||
else
|
||||
return packet<LoadMode,PacketType>(RowsAtCompileTime == 1 ? 0 : index,
|
||||
RowsAtCompileTime == 1 ? index : 0);
|
||||
}
|
||||
|
||||
|
||||
template<int StoreMode, typename PacketType>
|
||||
EIGEN_STRONG_INLINE
|
||||
void writePacket(Index row, Index col, const PacketType& x)
|
||||
void writePacket(Index row, Index col, const PacketType& x)
|
||||
{
|
||||
return m_argImpl.template writePacket<StoreMode,PacketType>(m_startRow.value() + row, m_startCol.value() + col, x);
|
||||
return m_argImpl.template writePacket<StoreMode,PacketType>(m_startRow.value() + row, m_startCol.value() + col, x);
|
||||
}
|
||||
|
||||
|
||||
template<int StoreMode, typename PacketType>
|
||||
EIGEN_STRONG_INLINE
|
||||
void writePacket(Index index, const PacketType& x)
|
||||
void writePacket(Index index, const PacketType& x)
|
||||
{
|
||||
if (ForwardLinearAccess)
|
||||
return m_argImpl.template writePacket<StoreMode,PacketType>(m_linear_offset.value() + index, x);
|
||||
@@ -1170,12 +1174,12 @@ struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IndexBa
|
||||
RowsAtCompileTime == 1 ? index : 0,
|
||||
x);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
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
|
||||
@@ -1186,7 +1190,7 @@ protected:
|
||||
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);
|
||||
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 */)
|
||||
@@ -1200,10 +1204,10 @@ protected:
|
||||
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;
|
||||
// all action is via the data() as returned by the Block expression.
|
||||
|
||||
template<typename ArgType, int BlockRows, int BlockCols, bool InnerPanel>
|
||||
template<typename ArgType, int BlockRows, int BlockCols, bool InnerPanel>
|
||||
struct block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel, /* HasDirectAccess */ true>
|
||||
: mapbase_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>,
|
||||
typename Block<ArgType, BlockRows, BlockCols, InnerPanel>::PlainObject>
|
||||
@@ -1213,7 +1217,7 @@ struct block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel, /* HasDirectAc
|
||||
|
||||
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
|
||||
eigen_assert(((internal::UIntPtr(block.data()) % EIGEN_PLAIN_ENUM_MAX(1,evaluator<XprType>::Alignment)) == 0) && "data is not aligned");
|
||||
@@ -1236,7 +1240,7 @@ struct evaluator<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >
|
||||
evaluator<ElseMatrixType>::CoeffReadCost),
|
||||
|
||||
Flags = (unsigned int)evaluator<ThenMatrixType>::Flags & evaluator<ElseMatrixType>::Flags & HereditaryBits,
|
||||
|
||||
|
||||
Alignment = EIGEN_PLAIN_ENUM_MIN(evaluator<ThenMatrixType>::Alignment, evaluator<ElseMatrixType>::Alignment)
|
||||
};
|
||||
|
||||
@@ -1248,7 +1252,7 @@ struct evaluator<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >
|
||||
{
|
||||
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
||||
}
|
||||
|
||||
|
||||
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
@@ -1268,7 +1272,7 @@ struct evaluator<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >
|
||||
else
|
||||
return m_elseImpl.coeff(index);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
evaluator<ConditionMatrixType> m_conditionImpl;
|
||||
evaluator<ThenMatrixType> m_thenImpl;
|
||||
@@ -1278,7 +1282,7 @@ protected:
|
||||
|
||||
// -------------------- Replicate --------------------
|
||||
|
||||
template<typename ArgType, int RowFactor, int ColFactor>
|
||||
template<typename ArgType, int RowFactor, int ColFactor>
|
||||
struct unary_evaluator<Replicate<ArgType, RowFactor, ColFactor> >
|
||||
: evaluator_base<Replicate<ArgType, RowFactor, ColFactor> >
|
||||
{
|
||||
@@ -1289,12 +1293,12 @@ struct unary_evaluator<Replicate<ArgType, RowFactor, ColFactor> >
|
||||
};
|
||||
typedef typename internal::nested_eval<ArgType,Factor>::type ArgTypeNested;
|
||||
typedef typename internal::remove_all<ArgTypeNested>::type ArgTypeNestedCleaned;
|
||||
|
||||
|
||||
enum {
|
||||
CoeffReadCost = evaluator<ArgTypeNestedCleaned>::CoeffReadCost,
|
||||
LinearAccessMask = XprType::IsVectorAtCompileTime ? LinearAccessBit : 0,
|
||||
Flags = (evaluator<ArgTypeNestedCleaned>::Flags & (HereditaryBits|LinearAccessMask) & ~RowMajorBit) | (traits<XprType>::Flags & RowMajorBit),
|
||||
|
||||
|
||||
Alignment = evaluator<ArgTypeNestedCleaned>::Alignment
|
||||
};
|
||||
|
||||
@@ -1305,7 +1309,7 @@ struct unary_evaluator<Replicate<ArgType, RowFactor, ColFactor> >
|
||||
m_rows(replicate.nestedExpression().rows()),
|
||||
m_cols(replicate.nestedExpression().cols())
|
||||
{}
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
CoeffReturnType coeff(Index row, Index col) const
|
||||
{
|
||||
@@ -1316,10 +1320,10 @@ struct unary_evaluator<Replicate<ArgType, RowFactor, ColFactor> >
|
||||
const Index actual_col = internal::traits<XprType>::ColsAtCompileTime==1 ? 0
|
||||
: ColFactor==1 ? col
|
||||
: col % m_cols.value();
|
||||
|
||||
|
||||
return m_argImpl.coeff(actual_row, actual_col);
|
||||
}
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
CoeffReturnType coeff(Index index) const
|
||||
{
|
||||
@@ -1327,7 +1331,7 @@ struct unary_evaluator<Replicate<ArgType, RowFactor, ColFactor> >
|
||||
const Index actual_index = internal::traits<XprType>::RowsAtCompileTime==1
|
||||
? (ColFactor==1 ? index : index%m_cols.value())
|
||||
: (RowFactor==1 ? index : index%m_rows.value());
|
||||
|
||||
|
||||
return m_argImpl.coeff(actual_index);
|
||||
}
|
||||
|
||||
@@ -1344,7 +1348,7 @@ struct unary_evaluator<Replicate<ArgType, RowFactor, ColFactor> >
|
||||
|
||||
return m_argImpl.template packet<LoadMode,PacketType>(actual_row, actual_col);
|
||||
}
|
||||
|
||||
|
||||
template<int LoadMode, typename PacketType>
|
||||
EIGEN_STRONG_INLINE
|
||||
PacketType packet(Index index) const
|
||||
@@ -1355,7 +1359,7 @@ struct unary_evaluator<Replicate<ArgType, RowFactor, ColFactor> >
|
||||
|
||||
return m_argImpl.template packet<LoadMode,PacketType>(actual_index);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
const ArgTypeNested m_arg;
|
||||
evaluator<ArgTypeNestedCleaned> m_argImpl;
|
||||
@@ -1487,9 +1491,9 @@ struct unary_evaluator<Reverse<ArgType, Direction> >
|
||||
ReversePacket = (Direction == BothDirections)
|
||||
|| ((Direction == Vertical) && IsColMajor)
|
||||
|| ((Direction == Horizontal) && IsRowMajor),
|
||||
|
||||
|
||||
CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
|
||||
|
||||
|
||||
// let's enable LinearAccess only with vectorization because of the product overhead
|
||||
// FIXME enable DirectAccess with negative strides?
|
||||
Flags0 = evaluator<ArgType>::Flags,
|
||||
@@ -1498,7 +1502,7 @@ struct unary_evaluator<Reverse<ArgType, Direction> >
|
||||
? LinearAccessBit : 0,
|
||||
|
||||
Flags = int(Flags0) & (HereditaryBits | PacketAccessBit | LinearAccess),
|
||||
|
||||
|
||||
Alignment = 0 // FIXME in some rare cases, Alignment could be preserved, like a Vector4f.
|
||||
};
|
||||
|
||||
@@ -1508,7 +1512,7 @@ struct unary_evaluator<Reverse<ArgType, Direction> >
|
||||
m_rows(ReverseRow ? reverse.nestedExpression().rows() : 1),
|
||||
m_cols(ReverseCol ? reverse.nestedExpression().cols() : 1)
|
||||
{ }
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
CoeffReturnType coeff(Index row, Index col) const
|
||||
{
|
||||
@@ -1583,7 +1587,7 @@ struct unary_evaluator<Reverse<ArgType, Direction> >
|
||||
m_argImpl.template writePacket<LoadMode>
|
||||
(m_rows.value() * m_cols.value() - index - PacketSize, preverse(x));
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
evaluator<ArgType> m_argImpl;
|
||||
|
||||
@@ -1601,12 +1605,12 @@ struct evaluator<Diagonal<ArgType, DiagIndex> >
|
||||
: evaluator_base<Diagonal<ArgType, DiagIndex> >
|
||||
{
|
||||
typedef Diagonal<ArgType, DiagIndex> XprType;
|
||||
|
||||
|
||||
enum {
|
||||
CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
|
||||
|
||||
|
||||
Flags = (unsigned int)(evaluator<ArgType>::Flags & (HereditaryBits | DirectAccessBit) & ~RowMajorBit) | LinearAccessBit,
|
||||
|
||||
|
||||
Alignment = 0
|
||||
};
|
||||
|
||||
@@ -1615,7 +1619,7 @@ struct evaluator<Diagonal<ArgType, DiagIndex> >
|
||||
: m_argImpl(diagonal.nestedExpression()),
|
||||
m_index(diagonal.index())
|
||||
{ }
|
||||
|
||||
|
||||
typedef typename XprType::Scalar Scalar;
|
||||
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
||||
|
||||
@@ -1648,8 +1652,10 @@ protected:
|
||||
const internal::variable_if_dynamicindex<Index, XprType::DiagIndex> m_index;
|
||||
|
||||
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 Index colOffset() const { return m_index.value() > 0 ? m_index.value() : 0; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
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; }
|
||||
};
|
||||
|
||||
|
||||
@@ -1673,25 +1679,25 @@ class EvalToTemp
|
||||
: public dense_xpr_base<EvalToTemp<ArgType> >::type
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
typedef typename dense_xpr_base<EvalToTemp>::type Base;
|
||||
EIGEN_GENERIC_PUBLIC_INTERFACE(EvalToTemp)
|
||||
|
||||
|
||||
explicit EvalToTemp(const ArgType& arg)
|
||||
: m_arg(arg)
|
||||
{ }
|
||||
|
||||
|
||||
const ArgType& arg() const
|
||||
{
|
||||
return m_arg;
|
||||
}
|
||||
|
||||
Index rows() const
|
||||
EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
|
||||
{
|
||||
return m_arg.rows();
|
||||
}
|
||||
|
||||
Index cols() const
|
||||
EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT
|
||||
{
|
||||
return m_arg.cols();
|
||||
}
|
||||
@@ -1699,7 +1705,7 @@ class EvalToTemp
|
||||
private:
|
||||
const ArgType& m_arg;
|
||||
};
|
||||
|
||||
|
||||
template<typename ArgType>
|
||||
struct evaluator<EvalToTemp<ArgType> >
|
||||
: public evaluator<typename ArgType::PlainObject>
|
||||
@@ -1707,7 +1713,7 @@ struct evaluator<EvalToTemp<ArgType> >
|
||||
typedef EvalToTemp<ArgType> XprType;
|
||||
typedef typename ArgType::PlainObject PlainObject;
|
||||
typedef evaluator<PlainObject> Base;
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr)
|
||||
: m_result(xpr.arg())
|
||||
{
|
||||
|
||||
@@ -74,7 +74,7 @@ class CwiseBinaryOpImpl;
|
||||
* \sa MatrixBase::binaryExpr(const MatrixBase<OtherDerived> &,const CustomBinaryOp &) const, class CwiseUnaryOp, class CwiseNullaryOp
|
||||
*/
|
||||
template<typename BinaryOp, typename LhsType, typename RhsType>
|
||||
class CwiseBinaryOp :
|
||||
class CwiseBinaryOp :
|
||||
public CwiseBinaryOpImpl<
|
||||
BinaryOp, LhsType, RhsType,
|
||||
typename internal::cwise_promote_storage_type<typename internal::traits<LhsType>::StorageKind,
|
||||
@@ -83,7 +83,7 @@ class CwiseBinaryOp :
|
||||
internal::no_assignment_operator
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
typedef typename internal::remove_all<BinaryOp>::type Functor;
|
||||
typedef typename internal::remove_all<LhsType>::type Lhs;
|
||||
typedef typename internal::remove_all<RhsType>::type Rhs;
|
||||
@@ -116,21 +116,15 @@ class CwiseBinaryOp :
|
||||
eigen_assert(aLhs.rows() == aRhs.rows() && aLhs.cols() == aRhs.cols());
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
Index rows() const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
Index rows() const EIGEN_NOEXCEPT {
|
||||
// return the fixed size type if available to enable compile time optimizations
|
||||
if (internal::traits<typename internal::remove_all<LhsNested>::type>::RowsAtCompileTime==Dynamic)
|
||||
return m_rhs.rows();
|
||||
else
|
||||
return m_lhs.rows();
|
||||
return internal::traits<typename internal::remove_all<LhsNested>::type>::RowsAtCompileTime==Dynamic ? m_rhs.rows() : m_lhs.rows();
|
||||
}
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
Index cols() const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
Index cols() const EIGEN_NOEXCEPT {
|
||||
// return the fixed size type if available to enable compile time optimizations
|
||||
if (internal::traits<typename internal::remove_all<LhsNested>::type>::ColsAtCompileTime==Dynamic)
|
||||
return m_rhs.cols();
|
||||
else
|
||||
return m_lhs.cols();
|
||||
return internal::traits<typename internal::remove_all<LhsNested>::type>::ColsAtCompileTime==Dynamic ? m_rhs.cols() : m_lhs.cols();
|
||||
}
|
||||
|
||||
/** \returns the left hand side nested expression */
|
||||
|
||||
@@ -74,10 +74,10 @@ class CwiseNullaryOp : public internal::dense_xpr_base< CwiseNullaryOp<NullaryOp
|
||||
&& (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Index rows() const { return m_rows.value(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Index cols() const { return m_cols.value(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
Index rows() const { return m_rows.value(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
Index cols() const { return m_cols.value(); }
|
||||
|
||||
/** \returns the functor representing the nullary operation */
|
||||
EIGEN_DEVICE_FUNC
|
||||
@@ -131,7 +131,7 @@ DenseBase<Derived>::NullaryExpr(Index rows, Index cols, const CustomNullaryOp& f
|
||||
*
|
||||
* Here is an example with C++11 random generators: \include random_cpp11.cpp
|
||||
* Output: \verbinclude random_cpp11.out
|
||||
*
|
||||
*
|
||||
* \sa class CwiseNullaryOp
|
||||
*/
|
||||
template<typename Derived>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#ifndef EIGEN_CWISE_UNARY_OP_H
|
||||
#define EIGEN_CWISE_UNARY_OP_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
template<typename UnaryOp, typename XprType>
|
||||
@@ -24,7 +24,7 @@ struct traits<CwiseUnaryOp<UnaryOp, XprType> >
|
||||
typedef typename XprType::Nested XprTypeNested;
|
||||
typedef typename remove_reference<XprTypeNested>::type _XprTypeNested;
|
||||
enum {
|
||||
Flags = _XprTypeNested::Flags & RowMajorBit
|
||||
Flags = _XprTypeNested::Flags & RowMajorBit
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -65,10 +65,10 @@ class CwiseUnaryOp : public CwiseUnaryOpImpl<UnaryOp, XprType, typename internal
|
||||
explicit CwiseUnaryOp(const XprType& xpr, const UnaryOp& func = UnaryOp())
|
||||
: m_xpr(xpr), m_functor(func) {}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
Index rows() const { return m_xpr.rows(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
Index cols() const { return m_xpr.cols(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
Index rows() const EIGEN_NOEXCEPT { return m_xpr.rows(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
Index cols() const EIGEN_NOEXCEPT { return m_xpr.cols(); }
|
||||
|
||||
/** \returns the functor representing the unary operation */
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
|
||||
@@ -69,8 +69,10 @@ class CwiseUnaryView : public CwiseUnaryViewImpl<ViewOp, MatrixType, typename in
|
||||
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryView)
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rows() const { return m_matrix.rows(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index cols() const { return m_matrix.cols(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
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 */
|
||||
EIGEN_DEVICE_FUNC const ViewOp& functor() const { return m_functor; }
|
||||
@@ -108,16 +110,16 @@ class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense>
|
||||
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryViewImpl)
|
||||
|
||||
|
||||
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 Index innerStride() const
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index innerStride() const
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
|
||||
// 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.
|
||||
static inline void check_DenseIndex_is_signed() {
|
||||
@@ -22,7 +22,7 @@ static inline void check_DenseIndex_is_signed() {
|
||||
}
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
|
||||
/** \class DenseBase
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
@@ -64,12 +64,12 @@ template<typename Derived> class DenseBase
|
||||
|
||||
/** The numeric type of the expression' coefficients, e.g. float, double, int or std::complex<float>, etc. */
|
||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||
|
||||
|
||||
/** The numeric type of the expression' coefficients, e.g. float, double, int or std::complex<float>, etc.
|
||||
*
|
||||
* It is an alias for the Scalar type */
|
||||
typedef Scalar value_type;
|
||||
|
||||
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
typedef DenseCoeffsBase<Derived, internal::accessors_level<Derived>::value> Base;
|
||||
|
||||
@@ -158,7 +158,7 @@ template<typename Derived> class DenseBase
|
||||
* 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,
|
||||
/**< This value is equal to Tensor::NumDimensions, i.e. 0 for scalars, 1 for vectors,
|
||||
* and 2 for matrices.
|
||||
*/
|
||||
|
||||
@@ -175,11 +175,11 @@ template<typename Derived> class DenseBase
|
||||
InnerStrideAtCompileTime = internal::inner_stride_at_compile_time<Derived>::ret,
|
||||
OuterStrideAtCompileTime = internal::outer_stride_at_compile_time<Derived>::ret
|
||||
};
|
||||
|
||||
|
||||
typedef typename internal::find_best_packet<Scalar,SizeAtCompileTime>::type PacketScalar;
|
||||
|
||||
enum { IsPlainObjectBase = 0 };
|
||||
|
||||
|
||||
/** The plain matrix type corresponding to this expression.
|
||||
* \sa PlainObject */
|
||||
typedef Matrix<typename internal::traits<Derived>::Scalar,
|
||||
@@ -189,7 +189,7 @@ template<typename Derived> class DenseBase
|
||||
internal::traits<Derived>::MaxRowsAtCompileTime,
|
||||
internal::traits<Derived>::MaxColsAtCompileTime
|
||||
> PlainMatrix;
|
||||
|
||||
|
||||
/** The plain array type corresponding to this expression.
|
||||
* \sa PlainObject */
|
||||
typedef Array<typename internal::traits<Derived>::Scalar,
|
||||
@@ -211,7 +211,7 @@ template<typename Derived> class DenseBase
|
||||
|
||||
/** \returns the number of nonzero coefficients which is in practice the number
|
||||
* of stored coefficients. */
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index nonZeros() const { return size(); }
|
||||
|
||||
/** \returns the outer size.
|
||||
@@ -219,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
|
||||
* with respect to the \ref TopicStorageOrders "storage order", i.e., the number of columns for a
|
||||
* column-major matrix, and the number of rows for a row-major matrix. */
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
Index outerSize() const
|
||||
{
|
||||
return IsVectorAtCompileTime ? 1
|
||||
@@ -229,9 +229,9 @@ template<typename Derived> class DenseBase
|
||||
/** \returns the inner size.
|
||||
*
|
||||
* \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. */
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
Index innerSize() const
|
||||
{
|
||||
return IsVectorAtCompileTime ? this->size()
|
||||
@@ -411,7 +411,7 @@ template<typename Derived> class DenseBase
|
||||
// size types on MSVC.
|
||||
return typename internal::eval<Derived>::type(derived());
|
||||
}
|
||||
|
||||
|
||||
/** swaps *this with the expression \a other.
|
||||
*
|
||||
*/
|
||||
@@ -449,18 +449,58 @@ template<typename Derived> class DenseBase
|
||||
|
||||
EIGEN_DEVICE_FUNC Scalar prod() const;
|
||||
|
||||
template<int NaNPropagation>
|
||||
EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar minCoeff() const;
|
||||
template<int NaNPropagation>
|
||||
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;
|
||||
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;
|
||||
template<typename IndexType> EIGEN_DEVICE_FUNC
|
||||
template<int NaNPropagation, typename IndexType>
|
||||
EIGEN_DEVICE_FUNC
|
||||
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;
|
||||
|
||||
// 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>
|
||||
EIGEN_DEVICE_FUNC
|
||||
Scalar redux(const BinaryOp& func) const;
|
||||
|
||||
@@ -27,7 +27,7 @@ template<typename T> struct add_const_on_value_type_if_arithmetic
|
||||
*
|
||||
* This class defines the \c operator() \c const function and friends, which can be used to read specific
|
||||
* entries of a matrix or array.
|
||||
*
|
||||
*
|
||||
* \sa DenseCoeffsBase<Derived, WriteAccessors>, DenseCoeffsBase<Derived, DirectAccessors>,
|
||||
* \ref TopicClassHierarchy
|
||||
*/
|
||||
@@ -295,7 +295,7 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
||||
* 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
|
||||
* defines the const variant for reading specific entries.
|
||||
*
|
||||
*
|
||||
* \sa DenseCoeffsBase<Derived, DirectAccessors>, \ref TopicClassHierarchy
|
||||
*/
|
||||
template<typename Derived>
|
||||
@@ -495,7 +495,7 @@ class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived
|
||||
*
|
||||
* \sa outerStride(), rowStride(), colStride()
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index innerStride() const
|
||||
{
|
||||
return derived().innerStride();
|
||||
@@ -506,14 +506,14 @@ class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived
|
||||
*
|
||||
* \sa innerStride(), rowStride(), colStride()
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index outerStride() const
|
||||
{
|
||||
return derived().outerStride();
|
||||
}
|
||||
|
||||
// FIXME shall we remove it ?
|
||||
inline Index stride() const
|
||||
EIGEN_CONSTEXPR inline Index stride() const
|
||||
{
|
||||
return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
|
||||
}
|
||||
@@ -522,7 +522,7 @@ class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived
|
||||
*
|
||||
* \sa innerStride(), outerStride(), colStride()
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index rowStride() const
|
||||
{
|
||||
return Derived::IsRowMajor ? outerStride() : innerStride();
|
||||
@@ -532,7 +532,7 @@ class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived
|
||||
*
|
||||
* \sa innerStride(), outerStride(), rowStride()
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index colStride() const
|
||||
{
|
||||
return Derived::IsRowMajor ? innerStride() : outerStride();
|
||||
@@ -570,8 +570,8 @@ class DenseCoeffsBase<Derived, DirectWriteAccessors>
|
||||
*
|
||||
* \sa outerStride(), rowStride(), colStride()
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index innerStride() const
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index innerStride() const EIGEN_NOEXCEPT
|
||||
{
|
||||
return derived().innerStride();
|
||||
}
|
||||
@@ -581,14 +581,14 @@ class DenseCoeffsBase<Derived, DirectWriteAccessors>
|
||||
*
|
||||
* \sa innerStride(), rowStride(), colStride()
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index outerStride() const
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index outerStride() const EIGEN_NOEXCEPT
|
||||
{
|
||||
return derived().outerStride();
|
||||
}
|
||||
|
||||
// FIXME shall we remove it ?
|
||||
inline Index stride() const
|
||||
EIGEN_CONSTEXPR inline Index stride() const EIGEN_NOEXCEPT
|
||||
{
|
||||
return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
|
||||
}
|
||||
@@ -597,8 +597,8 @@ class DenseCoeffsBase<Derived, DirectWriteAccessors>
|
||||
*
|
||||
* \sa innerStride(), outerStride(), colStride()
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index rowStride() const
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index rowStride() const EIGEN_NOEXCEPT
|
||||
{
|
||||
return Derived::IsRowMajor ? outerStride() : innerStride();
|
||||
}
|
||||
@@ -607,8 +607,8 @@ class DenseCoeffsBase<Derived, DirectWriteAccessors>
|
||||
*
|
||||
* \sa innerStride(), outerStride(), rowStride()
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index colStride() const
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index colStride() const EIGEN_NOEXCEPT
|
||||
{
|
||||
return Derived::IsRowMajor ? innerStride() : outerStride();
|
||||
}
|
||||
@@ -619,7 +619,7 @@ namespace internal {
|
||||
template<int Alignment, typename Derived, bool JustReturnZero>
|
||||
struct first_aligned_impl
|
||||
{
|
||||
static inline Index run(const Derived&)
|
||||
static EIGEN_CONSTEXPR inline Index run(const Derived&) EIGEN_NOEXCEPT
|
||||
{ return 0; }
|
||||
};
|
||||
|
||||
|
||||
@@ -47,20 +47,20 @@ struct plain_array
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
plain_array()
|
||||
{
|
||||
{
|
||||
check_static_allocation_size<T,Size>();
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
plain_array(constructor_without_unaligned_array_assert)
|
||||
{
|
||||
{
|
||||
check_static_allocation_size<T,Size>();
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT)
|
||||
#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask)
|
||||
#elif EIGEN_GNUC_AT_LEAST(4,7)
|
||||
#elif EIGEN_GNUC_AT_LEAST(4,7)
|
||||
// GCC 4.7 is too aggressive in its optimizations and remove the alignment test based on the fact the array is declared to be aligned.
|
||||
// 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:
|
||||
@@ -85,15 +85,15 @@ struct plain_array<T, Size, MatrixOrArrayOptions, 8>
|
||||
EIGEN_ALIGN_TO_BOUNDARY(8) T array[Size];
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
plain_array()
|
||||
plain_array()
|
||||
{
|
||||
EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(7);
|
||||
check_static_allocation_size<T,Size>();
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
plain_array(constructor_without_unaligned_array_assert)
|
||||
{
|
||||
plain_array(constructor_without_unaligned_array_assert)
|
||||
{
|
||||
check_static_allocation_size<T,Size>();
|
||||
}
|
||||
};
|
||||
@@ -104,15 +104,15 @@ struct plain_array<T, Size, MatrixOrArrayOptions, 16>
|
||||
EIGEN_ALIGN_TO_BOUNDARY(16) T array[Size];
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
plain_array()
|
||||
{
|
||||
plain_array()
|
||||
{
|
||||
EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(15);
|
||||
check_static_allocation_size<T,Size>();
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
plain_array(constructor_without_unaligned_array_assert)
|
||||
{
|
||||
plain_array(constructor_without_unaligned_array_assert)
|
||||
{
|
||||
check_static_allocation_size<T,Size>();
|
||||
}
|
||||
};
|
||||
@@ -123,15 +123,15 @@ struct plain_array<T, Size, MatrixOrArrayOptions, 32>
|
||||
EIGEN_ALIGN_TO_BOUNDARY(32) T array[Size];
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
plain_array()
|
||||
plain_array()
|
||||
{
|
||||
EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(31);
|
||||
check_static_allocation_size<T,Size>();
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
plain_array(constructor_without_unaligned_array_assert)
|
||||
{
|
||||
plain_array(constructor_without_unaligned_array_assert)
|
||||
{
|
||||
check_static_allocation_size<T,Size>();
|
||||
}
|
||||
};
|
||||
@@ -142,15 +142,15 @@ struct plain_array<T, Size, MatrixOrArrayOptions, 64>
|
||||
EIGEN_ALIGN_TO_BOUNDARY(64) T array[Size];
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
plain_array()
|
||||
{
|
||||
plain_array()
|
||||
{
|
||||
EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(63);
|
||||
check_static_allocation_size<T,Size>();
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
plain_array(constructor_without_unaligned_array_assert)
|
||||
{
|
||||
plain_array(constructor_without_unaligned_array_assert)
|
||||
{
|
||||
check_static_allocation_size<T,Size>();
|
||||
}
|
||||
};
|
||||
@@ -190,15 +190,15 @@ template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseSt
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
: m_data(internal::constructor_without_unaligned_array_assert()) {}
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC
|
||||
DenseStorage(const DenseStorage& other) : m_data(other.m_data) {
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size)
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC
|
||||
DenseStorage& operator=(const DenseStorage& other)
|
||||
{
|
||||
{
|
||||
if (this != &other) m_data = other.m_data;
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
#if EIGEN_HAS_RVALUE_REFERENCES
|
||||
EIGEN_DEVICE_FUNC DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT
|
||||
@@ -222,8 +222,8 @@ template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseSt
|
||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
|
||||
numext::swap(m_data, other.m_data);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC static Index rows(void) {return _Rows;}
|
||||
EIGEN_DEVICE_FUNC static Index cols(void) {return _Cols;}
|
||||
EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index rows(void) EIGEN_NOEXCEPT {return _Rows;}
|
||||
EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index cols(void) EIGEN_NOEXCEPT {return _Cols;}
|
||||
EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {}
|
||||
EIGEN_DEVICE_FUNC void resize(Index,Index,Index) {}
|
||||
EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
|
||||
@@ -240,8 +240,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(Index,Index,Index) {}
|
||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& ) {}
|
||||
EIGEN_DEVICE_FUNC static Index rows(void) {return _Rows;}
|
||||
EIGEN_DEVICE_FUNC static Index cols(void) {return _Cols;}
|
||||
EIGEN_DEVICE_FUNC 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 resize(Index,Index,Index) {}
|
||||
EIGEN_DEVICE_FUNC const T *data() const { return 0; }
|
||||
@@ -269,15 +269,15 @@ template<typename T, int Size, int _Options> class DenseStorage<T, Size, Dynamic
|
||||
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) {}
|
||||
EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows), m_cols(other.m_cols) {}
|
||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
||||
{
|
||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
m_data = other.m_data;
|
||||
m_rows = other.m_rows;
|
||||
m_cols = other.m_cols;
|
||||
}
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index cols) : m_rows(rows), m_cols(cols) {}
|
||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& other)
|
||||
@@ -304,14 +304,14 @@ template<typename T, int Size, int _Cols, int _Options> class DenseStorage<T, Si
|
||||
EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
: 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& operator=(const DenseStorage& other)
|
||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
m_data = other.m_data;
|
||||
m_rows = other.m_rows;
|
||||
}
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index) : m_rows(rows) {}
|
||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& other)
|
||||
@@ -319,8 +319,8 @@ template<typename T, int Size, int _Cols, int _Options> class DenseStorage<T, Si
|
||||
numext::swap(m_data,other.m_data);
|
||||
numext::swap(m_rows,other.m_rows);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC Index rows(void) const {return m_rows;}
|
||||
EIGEN_DEVICE_FUNC Index cols(void) const {return _Cols;}
|
||||
EIGEN_DEVICE_FUNC 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 resize(Index, Index rows, Index) { m_rows = rows; }
|
||||
EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
|
||||
@@ -351,8 +351,8 @@ template<typename T, int Size, int _Rows, int _Options> class DenseStorage<T, Si
|
||||
numext::swap(m_data,other.m_data);
|
||||
numext::swap(m_cols,other.m_cols);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC Index rows(void) const {return _Rows;}
|
||||
EIGEN_DEVICE_FUNC Index cols(void) const {return m_cols;}
|
||||
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; }
|
||||
@@ -419,8 +419,8 @@ template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynam
|
||||
numext::swap(m_rows,other.m_rows);
|
||||
numext::swap(m_cols,other.m_cols);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC Index rows(void) const {return m_rows;}
|
||||
EIGEN_DEVICE_FUNC Index cols(void) const {return 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)
|
||||
{
|
||||
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*m_cols);
|
||||
@@ -474,7 +474,7 @@ template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Ro
|
||||
this->swap(tmp);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
#if EIGEN_HAS_RVALUE_REFERENCES
|
||||
EIGEN_DEVICE_FUNC
|
||||
DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT
|
||||
@@ -497,8 +497,8 @@ template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Ro
|
||||
numext::swap(m_data,other.m_data);
|
||||
numext::swap(m_cols,other.m_cols);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC static Index rows(void) {return _Rows;}
|
||||
EIGEN_DEVICE_FUNC Index cols(void) const {return m_cols;}
|
||||
EIGEN_DEVICE_FUNC 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)
|
||||
{
|
||||
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, _Rows*m_cols);
|
||||
@@ -550,7 +550,7 @@ template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dyn
|
||||
this->swap(tmp);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
#if EIGEN_HAS_RVALUE_REFERENCES
|
||||
EIGEN_DEVICE_FUNC
|
||||
DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT
|
||||
@@ -573,8 +573,8 @@ template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dyn
|
||||
numext::swap(m_data,other.m_data);
|
||||
numext::swap(m_rows,other.m_rows);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC Index rows(void) const {return m_rows;}
|
||||
EIGEN_DEVICE_FUNC static Index cols(void) {return _Cols;}
|
||||
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)
|
||||
{
|
||||
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*_Cols);
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#ifndef EIGEN_DIAGONAL_H
|
||||
#define EIGEN_DIAGONAL_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
/** \class Diagonal
|
||||
* \ingroup Core_Module
|
||||
@@ -84,20 +84,16 @@ template<typename MatrixType, int _DiagIndex> class Diagonal
|
||||
: numext::mini<Index>(m_matrix.rows(),m_matrix.cols()-m_index.value());
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index cols() const { return 1; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index cols() const EIGEN_NOEXCEPT { return 1; }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index innerStride() const
|
||||
{
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index innerStride() const EIGEN_NOEXCEPT {
|
||||
return m_matrix.outerStride() + 1;
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index outerStride() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index outerStride() const EIGEN_NOEXCEPT { return 0; }
|
||||
|
||||
typedef typename internal::conditional<
|
||||
internal::is_lvalue<MatrixType>::value,
|
||||
@@ -149,8 +145,8 @@ template<typename MatrixType, int _DiagIndex> class Diagonal
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const typename internal::remove_all<typename MatrixType::Nested>::type&
|
||||
nestedExpression() const
|
||||
inline const typename internal::remove_all<typename MatrixType::Nested>::type&
|
||||
nestedExpression() const
|
||||
{
|
||||
return m_matrix;
|
||||
}
|
||||
@@ -167,12 +163,12 @@ template<typename MatrixType, int _DiagIndex> class Diagonal
|
||||
|
||||
private:
|
||||
// some compilers may fail to optimize std::max etc in case of compile-time constants...
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Index absDiagIndex() const { return m_index.value()>0 ? m_index.value() : -m_index.value(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Index rowOffset() const { return m_index.value()>0 ? 0 : -m_index.value(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Index colOffset() const { return m_index.value()>0 ? m_index.value() : 0; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
Index absDiagIndex() const EIGEN_NOEXCEPT { return m_index.value()>0 ? m_index.value() : -m_index.value(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
Index rowOffset() const EIGEN_NOEXCEPT { return m_index.value()>0 ? 0 : -m_index.value(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
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
|
||||
template<int LoadMode> typename MatrixType::PacketReturnType packet(Index) const;
|
||||
template<int LoadMode> typename MatrixType::PacketReturnType packet(Index,Index) const;
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Eigen {
|
||||
|
||||
/** \class EigenBase
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
*
|
||||
* Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor MatrixBase(T).
|
||||
*
|
||||
* In other words, an EigenBase object is an object that can be copied into a MatrixBase.
|
||||
@@ -29,7 +29,7 @@ namespace Eigen {
|
||||
template<typename Derived> struct EigenBase
|
||||
{
|
||||
// typedef typename internal::plain_matrix_type<Derived>::type PlainObject;
|
||||
|
||||
|
||||
/** \brief The interface type of indices
|
||||
* \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE.
|
||||
* \sa StorageIndex, \ref TopicPreprocessorDirectives.
|
||||
@@ -56,15 +56,15 @@ template<typename Derived> struct EigenBase
|
||||
{ return *static_cast<const Derived*>(this); }
|
||||
|
||||
/** \returns the number of rows. \sa cols(), RowsAtCompileTime */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index rows() const { return derived().rows(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index rows() const EIGEN_NOEXCEPT { return derived().rows(); }
|
||||
/** \returns the number of columns. \sa rows(), ColsAtCompileTime*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index cols() const { return derived().cols(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index cols() const EIGEN_NOEXCEPT { return derived().cols(); }
|
||||
/** \returns the number of coefficients, which is rows()*cols().
|
||||
* \sa rows(), cols(), SizeAtCompileTime. */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index size() const { return rows() * cols(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index size() const EIGEN_NOEXCEPT { return rows() * cols(); }
|
||||
|
||||
/** \internal Don't use it, but do the equivalent: \code dst = *this; \endcode */
|
||||
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 inline Index rows() const { return m_expression.rows(); }
|
||||
EIGEN_DEVICE_FUNC inline Index cols() const { return m_expression.cols(); }
|
||||
EIGEN_DEVICE_FUNC inline Index outerStride() const { return m_expression.outerStride(); }
|
||||
EIGEN_DEVICE_FUNC inline Index innerStride() const { return m_expression.innerStride(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index rows() const EIGEN_NOEXCEPT { return m_expression.rows(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
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
|
||||
{
|
||||
|
||||
@@ -684,7 +684,7 @@ Packet plog2(const Packet& a) {
|
||||
|
||||
/** \internal \returns the square-root of \a a (coeff-wise) */
|
||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||
Packet psqrt(const Packet& a) { EIGEN_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) */
|
||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#ifndef EIGEN_INVERSE_H
|
||||
#define EIGEN_INVERSE_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
template<typename XprType,typename StorageKind> class InverseImpl;
|
||||
|
||||
@@ -49,13 +49,13 @@ public:
|
||||
typedef typename internal::remove_all<XprTypeNested>::type XprTypeNestedCleaned;
|
||||
typedef typename internal::ref_selector<Inverse>::type Nested;
|
||||
typedef typename internal::remove_all<XprType>::type NestedExpression;
|
||||
|
||||
|
||||
explicit EIGEN_DEVICE_FUNC Inverse(const XprType &xpr)
|
||||
: m_xpr(xpr)
|
||||
{}
|
||||
|
||||
EIGEN_DEVICE_FUNC Index rows() const { return m_xpr.cols(); }
|
||||
EIGEN_DEVICE_FUNC Index cols() const { return m_xpr.rows(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { 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; }
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace internal {
|
||||
|
||||
/** \internal
|
||||
* \brief Default evaluator for Inverse expression.
|
||||
*
|
||||
*
|
||||
* This default evaluator for Inverse expression simply evaluate the inverse into a temporary
|
||||
* by a call to internal::call_assignment_no_alias.
|
||||
* Therefore, inverse implementers only have to specialize Assignment<Dst,Inverse<...>, ...> for
|
||||
@@ -96,7 +96,7 @@ struct unary_evaluator<Inverse<ArgType> >
|
||||
typedef Inverse<ArgType> InverseType;
|
||||
typedef typename InverseType::PlainObject PlainObject;
|
||||
typedef evaluator<PlainObject> Base;
|
||||
|
||||
|
||||
enum { Flags = Base::Flags | EvalBeforeNestingBit };
|
||||
|
||||
unary_evaluator(const InverseType& inv_xpr)
|
||||
@@ -105,11 +105,11 @@ struct unary_evaluator<Inverse<ArgType> >
|
||||
::new (static_cast<Base*>(this)) Base(m_result);
|
||||
internal::call_assignment_no_alias(m_result, inv_xpr);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
PlainObject m_result;
|
||||
};
|
||||
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#ifndef EIGEN_MAP_H
|
||||
#define EIGEN_MAP_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
template<typename PlainObjectType, int MapOptions, typename StrideType>
|
||||
@@ -104,13 +104,13 @@ template<typename PlainObjectType, int MapOptions, typename StrideType> class Ma
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline PointerType cast_to_pointer_type(PointerArgType ptr) { return ptr; }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index innerStride() const
|
||||
{
|
||||
return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index outerStride() const
|
||||
{
|
||||
return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
EIGEN_STATIC_ASSERT((int(internal::evaluator<Derived>::Flags) & LinearAccessBit) || Derived::IsVectorAtCompileTime, \
|
||||
YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT)
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
/** \ingroup Core_Module
|
||||
*
|
||||
@@ -87,9 +87,11 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
|
||||
typedef typename Base::CoeffReturnType CoeffReturnType;
|
||||
|
||||
/** \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() */
|
||||
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.
|
||||
*
|
||||
|
||||
@@ -214,12 +214,12 @@ struct imag_ref_default_impl
|
||||
template<typename Scalar>
|
||||
struct imag_ref_default_impl<Scalar, false>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static inline Scalar run(Scalar&)
|
||||
{
|
||||
return Scalar(0);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static inline const Scalar run(const Scalar&)
|
||||
{
|
||||
return Scalar(0);
|
||||
@@ -476,31 +476,59 @@ inline NewType cast(const OldType& x)
|
||||
* Implementation of round *
|
||||
****************************************************************************/
|
||||
|
||||
#if EIGEN_HAS_CXX11_MATH
|
||||
template<typename Scalar>
|
||||
struct round_impl {
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline Scalar run(const Scalar& x)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
|
||||
EIGEN_USING_STD(round);
|
||||
return Scalar(round(x));
|
||||
}
|
||||
};
|
||||
#else
|
||||
template<typename Scalar>
|
||||
struct round_impl
|
||||
template<typename Scalar>
|
||||
struct round_impl
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline Scalar run(const Scalar& x)
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline Scalar run(const Scalar& x)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
|
||||
EIGEN_USING_STD(floor);
|
||||
EIGEN_USING_STD(ceil);
|
||||
return (x > Scalar(0)) ? floor(x + Scalar(0.5)) : ceil(x - Scalar(0.5));
|
||||
}
|
||||
};
|
||||
EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
|
||||
#if EIGEN_HAS_CXX11_MATH
|
||||
EIGEN_USING_STD(round);
|
||||
#endif
|
||||
return Scalar(round(x));
|
||||
}
|
||||
};
|
||||
|
||||
#if !EIGEN_HAS_CXX11_MATH
|
||||
#if EIGEN_HAS_C99_MATH
|
||||
// Use ::roundf for float.
|
||||
template<>
|
||||
struct round_impl<float> {
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline float run(const float& x)
|
||||
{
|
||||
return ::roundf(x);
|
||||
}
|
||||
};
|
||||
#else
|
||||
template<typename Scalar>
|
||||
struct round_using_floor_ceil_impl
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline Scalar run(const Scalar& x)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
|
||||
// Without C99 round/roundf, resort to floor/ceil.
|
||||
EIGEN_USING_STD(floor);
|
||||
EIGEN_USING_STD(ceil);
|
||||
// If not enough precision to resolve a decimal at all, return the input.
|
||||
// Otherwise, adding 0.5 can trigger an increment by 1.
|
||||
const Scalar limit = Scalar(1ull << (NumTraits<Scalar>::digits() - 1));
|
||||
if (x >= limit || x <= -limit) {
|
||||
return x;
|
||||
}
|
||||
return (x > Scalar(0)) ? Scalar(floor(x + Scalar(0.5))) : Scalar(ceil(x - Scalar(0.5)));
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct round_impl<float> : round_using_floor_ceil_impl<float> {};
|
||||
|
||||
template<>
|
||||
struct round_impl<double> : round_using_floor_ceil_impl<double> {};
|
||||
#endif // EIGEN_HAS_C99_MATH
|
||||
#endif // !EIGEN_HAS_CXX11_MATH
|
||||
|
||||
template<typename Scalar>
|
||||
struct round_retval
|
||||
|
||||
@@ -29,7 +29,7 @@ private:
|
||||
required_alignment = unpacket_traits<PacketScalar>::alignment,
|
||||
packet_access_bit = (packet_traits<_Scalar>::Vectorizable && (EIGEN_UNALIGNED_VECTORIZE || (actual_alignment>=required_alignment))) ? PacketAccessBit : 0
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
typedef _Scalar Scalar;
|
||||
typedef Dense StorageKind;
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
Options = _Options,
|
||||
InnerStrideAtCompileTime = 1,
|
||||
OuterStrideAtCompileTime = (Options&RowMajor) ? ColsAtCompileTime : RowsAtCompileTime,
|
||||
|
||||
|
||||
// FIXME, the following flag in only used to define NeedsToAlign in PlainObjectBase
|
||||
EvaluatorFlags = LinearAccessBit | DirectAccessBit | packet_access_bit | row_major_bit,
|
||||
Alignment = actual_alignment
|
||||
@@ -278,7 +278,7 @@ class Matrix
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
Matrix& operator=(Matrix&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_assignable<Scalar>::value)
|
||||
{
|
||||
other.swap(*this);
|
||||
Base::operator=(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
@@ -297,24 +297,24 @@ class Matrix
|
||||
: 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
|
||||
@@ -351,7 +351,7 @@ class Matrix
|
||||
* This is useful for dynamic-size vectors. For fixed-size vectors,
|
||||
* it is redundant to pass these parameters, so one should use the default constructor
|
||||
* Matrix() instead.
|
||||
*
|
||||
*
|
||||
* \warning This constructor is disabled for fixed-size \c 1x1 matrices. For instance,
|
||||
* calling Matrix<double,1,1>(1) will call the initialization constructor: Matrix(const Scalar&).
|
||||
* For fixed-size \c 1x1 matrices it is therefore recommended to use the default
|
||||
@@ -367,7 +367,7 @@ class Matrix
|
||||
* This is useful for dynamic-size matrices. For fixed-size matrices,
|
||||
* it is redundant to pass these parameters, so one should use the default constructor
|
||||
* Matrix() instead.
|
||||
*
|
||||
*
|
||||
* \warning This constructor is disabled for fixed-size \c 1x2 and \c 2x1 vectors. For instance,
|
||||
* calling Matrix2f(2,1) will call the initialization constructor: Matrix(const Scalar& x, const Scalar& y).
|
||||
* For fixed-size \c 1x2 or \c 2x1 vectors it is therefore recommended to use the default
|
||||
@@ -376,7 +376,7 @@ class Matrix
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
Matrix(Index rows, Index cols);
|
||||
|
||||
|
||||
/** \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);
|
||||
@@ -423,8 +423,10 @@ class Matrix
|
||||
: Base(other.derived())
|
||||
{ }
|
||||
|
||||
EIGEN_DEVICE_FUNC inline Index innerStride() const { return 1; }
|
||||
EIGEN_DEVICE_FUNC inline Index outerStride() const { return this->innerSize(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index innerStride() const EIGEN_NOEXCEPT { return 1; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index outerStride() const EIGEN_NOEXCEPT { return this->innerSize(); }
|
||||
|
||||
/////////// Geometry module ///////////
|
||||
|
||||
@@ -463,14 +465,14 @@ class Matrix
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -45,8 +45,8 @@ template<typename ExpressionType> class NestByValue
|
||||
|
||||
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 inline Index cols() const { return m_expression.cols(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index rows() const EIGEN_NOEXCEPT { return m_expression.rows(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index cols() const EIGEN_NOEXCEPT { return m_expression.cols(); }
|
||||
|
||||
EIGEN_DEVICE_FUNC operator const ExpressionType&() const { return m_expression; }
|
||||
|
||||
|
||||
@@ -135,9 +135,18 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Tgt bit_cast(const Src& src) {
|
||||
* \li A dummy_precision() function returning a weak epsilon value. It is mainly used as a default
|
||||
* value by the fuzzy comparison operators.
|
||||
* \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
|
||||
* 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.
|
||||
* \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
|
||||
@@ -179,6 +188,18 @@ template<typename T> struct GenericNumTraits
|
||||
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()
|
||||
{
|
||||
@@ -186,7 +207,6 @@ template<typename T> struct GenericNumTraits
|
||||
return Real(0);
|
||||
}
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static inline T highest() {
|
||||
return (numext::numeric_limits<T>::max)();
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
|
||||
#if defined(EIGEN_INITIALIZE_MATRICES_BY_ZERO)
|
||||
# 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)
|
||||
# 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
|
||||
# undef EIGEN_INITIALIZE_COEFFS
|
||||
# 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::Flags;
|
||||
|
||||
template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map;
|
||||
friend class Eigen::Map<Derived, Unaligned>;
|
||||
typedef Eigen::Map<Derived, Unaligned> MapType;
|
||||
friend class Eigen::Map<const Derived, Unaligned>;
|
||||
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 const Eigen::Map<const Derived, AlignedMax> ConstAlignedMapType;
|
||||
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
|
||||
const Base& base() const { return *static_cast<const Base*>(this); }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
Index rows() const EIGEN_NOEXCEPT { return m_storage.rows(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
Index cols() const EIGEN_NOEXCEPT { return m_storage.cols(); }
|
||||
|
||||
/** 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.
|
||||
@@ -508,8 +500,8 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
EIGEN_DEVICE_FUNC
|
||||
PlainObjectBase& operator=(PlainObjectBase&& other) EIGEN_NOEXCEPT
|
||||
{
|
||||
using std::swap;
|
||||
swap(m_storage, other.m_storage);
|
||||
_check_template_params();
|
||||
m_storage = std::move(other.m_storage);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
@@ -530,11 +522,11 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
/** \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
|
||||
*
|
||||
* \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>
|
||||
@@ -548,7 +540,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
m_storage.data()[1] = a1;
|
||||
m_storage.data()[2] = a2;
|
||||
m_storage.data()[3] = a3;
|
||||
int i = 4;
|
||||
Index i = 4;
|
||||
auto x = {(m_storage.data()[i++] = args, 0)...};
|
||||
static_cast<void>(x);
|
||||
}
|
||||
@@ -576,7 +568,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
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());
|
||||
@@ -975,8 +967,8 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
EIGEN_DEVICE_FUNC
|
||||
static EIGEN_STRONG_INLINE void _check_template_params()
|
||||
{
|
||||
EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor)
|
||||
&& EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0)
|
||||
EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (int(Options)&RowMajor)==RowMajor)
|
||||
&& EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (int(Options)&RowMajor)==0)
|
||||
&& ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0))
|
||||
&& ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0))
|
||||
&& ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0))
|
||||
@@ -988,6 +980,17 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
}
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
|
||||
@@ -23,25 +23,25 @@ struct traits<Product<Lhs, Rhs, Option> >
|
||||
typedef typename remove_all<Rhs>::type RhsCleaned;
|
||||
typedef traits<LhsCleaned> LhsTraits;
|
||||
typedef traits<RhsCleaned> RhsTraits;
|
||||
|
||||
|
||||
typedef MatrixXpr XprKind;
|
||||
|
||||
|
||||
typedef typename ScalarBinaryOpTraits<typename traits<LhsCleaned>::Scalar, typename traits<RhsCleaned>::Scalar>::ReturnType Scalar;
|
||||
typedef typename product_promote_storage_type<typename LhsTraits::StorageKind,
|
||||
typename RhsTraits::StorageKind,
|
||||
internal::product_type<Lhs,Rhs>::ret>::ret StorageKind;
|
||||
typedef typename promote_index_type<typename LhsTraits::StorageIndex,
|
||||
typename RhsTraits::StorageIndex>::type StorageIndex;
|
||||
|
||||
|
||||
enum {
|
||||
RowsAtCompileTime = LhsTraits::RowsAtCompileTime,
|
||||
ColsAtCompileTime = RhsTraits::ColsAtCompileTime,
|
||||
MaxRowsAtCompileTime = LhsTraits::MaxRowsAtCompileTime,
|
||||
MaxColsAtCompileTime = RhsTraits::MaxColsAtCompileTime,
|
||||
|
||||
|
||||
// FIXME: only needed by GeneralMatrixMatrixTriangular
|
||||
InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(LhsTraits::ColsAtCompileTime, RhsTraits::RowsAtCompileTime),
|
||||
|
||||
|
||||
// The storage order is somewhat arbitrary here. The correct one will be determined through the evaluator.
|
||||
Flags = (MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1) ? RowMajorBit
|
||||
: (MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1) ? 0
|
||||
@@ -74,10 +74,10 @@ class Product : public ProductImpl<_Lhs,_Rhs,Option,
|
||||
internal::product_type<_Lhs,_Rhs>::ret>::ret>
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
typedef _Lhs Lhs;
|
||||
typedef _Rhs Rhs;
|
||||
|
||||
|
||||
typedef typename ProductImpl<
|
||||
Lhs, Rhs, Option,
|
||||
typename internal::product_promote_storage_type<typename internal::traits<Lhs>::StorageKind,
|
||||
@@ -98,10 +98,10 @@ class Product : public ProductImpl<_Lhs,_Rhs,Option,
|
||||
&& "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
|
||||
Index cols() const { return m_rhs.cols(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
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 EIGEN_STRONG_INLINE
|
||||
const LhsNestedCleaned& lhs() const { return m_lhs; }
|
||||
@@ -115,7 +115,7 @@ class Product : public ProductImpl<_Lhs,_Rhs,Option,
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
|
||||
template<typename Lhs, typename Rhs, int Option, int ProductTag = internal::product_type<Lhs,Rhs>::ret>
|
||||
class dense_product_base
|
||||
: public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
|
||||
@@ -131,7 +131,7 @@ class dense_product_base<Lhs, Rhs, Option, InnerProduct>
|
||||
public:
|
||||
using Base::derived;
|
||||
typedef typename Base::Scalar Scalar;
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE operator const Scalar() const
|
||||
{
|
||||
return internal::evaluator<ProductXpr>(derived()).coeff(0,0);
|
||||
@@ -153,25 +153,25 @@ class ProductImpl<Lhs,Rhs,Option,Dense>
|
||||
: public internal::dense_product_base<Lhs,Rhs,Option>
|
||||
{
|
||||
typedef Product<Lhs, Rhs, Option> Derived;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
typedef typename internal::dense_product_base<Lhs, Rhs, Option> Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
|
||||
protected:
|
||||
enum {
|
||||
IsOneByOne = (RowsAtCompileTime == 1 || RowsAtCompileTime == Dynamic) &&
|
||||
IsOneByOne = (RowsAtCompileTime == 1 || RowsAtCompileTime == Dynamic) &&
|
||||
(ColsAtCompileTime == 1 || ColsAtCompileTime == Dynamic),
|
||||
EnableCoeff = IsOneByOne || Option==LazyProduct
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar coeff(Index row, Index col) const
|
||||
{
|
||||
EIGEN_STATIC_ASSERT(EnableCoeff, THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS);
|
||||
eigen_assert( (Option==LazyProduct) || (this->rows() == 1 && this->cols() == 1) );
|
||||
|
||||
|
||||
return internal::evaluator<Derived>(derived()).coeff(row,col);
|
||||
}
|
||||
|
||||
@@ -179,11 +179,11 @@ class ProductImpl<Lhs,Rhs,Option,Dense>
|
||||
{
|
||||
EIGEN_STATIC_ASSERT(EnableCoeff, THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS);
|
||||
eigen_assert( (Option==LazyProduct) || (this->rows() == 1 && this->cols() == 1) );
|
||||
|
||||
|
||||
return internal::evaluator<Derived>(derived()).coeff(i);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -549,7 +549,7 @@ struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape,
|
||||
RhsCoeffReadCost = RhsEtorType::CoeffReadCost,
|
||||
CoeffReadCost = InnerSize==0 ? NumTraits<Scalar>::ReadCost
|
||||
: InnerSize == Dynamic ? HugeCost
|
||||
: InnerSize * (NumTraits<Scalar>::MulCost + LhsCoeffReadCost + RhsCoeffReadCost)
|
||||
: InnerSize * (NumTraits<Scalar>::MulCost + int(LhsCoeffReadCost) + int(RhsCoeffReadCost))
|
||||
+ (InnerSize - 1) * NumTraits<Scalar>::AddCost,
|
||||
|
||||
Unroll = CoeffReadCost <= EIGEN_UNROLLING_LIMIT,
|
||||
@@ -576,7 +576,7 @@ struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape,
|
||||
: (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
|
||||
: (bool(RhsRowMajor) && !CanVectorizeLhs),
|
||||
|
||||
Flags = ((unsigned int)(LhsFlags | RhsFlags) & HereditaryBits & ~RowMajorBit)
|
||||
Flags = ((int(LhsFlags) | int(RhsFlags)) & HereditaryBits & ~RowMajorBit)
|
||||
| (EvalToRowMajor ? RowMajorBit : 0)
|
||||
// TODO enable vectorization for mixed types
|
||||
| (SameType && (CanVectorizeLhs || CanVectorizeRhs) ? PacketAccessBit : 0)
|
||||
@@ -597,8 +597,8 @@ struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape,
|
||||
CanVectorizeInner = SameType
|
||||
&& LhsRowMajor
|
||||
&& (!RhsRowMajor)
|
||||
&& (LhsFlags & RhsFlags & ActualPacketAccessBit)
|
||||
&& (InnerSize % packet_traits<Scalar>::size == 0)
|
||||
&& (int(LhsFlags) & int(RhsFlags) & ActualPacketAccessBit)
|
||||
&& (int(InnerSize) % packet_traits<Scalar>::size == 0)
|
||||
};
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index row, Index col) const
|
||||
|
||||
@@ -419,25 +419,33 @@ DenseBase<Derived>::redux(const Func& func) const
|
||||
}
|
||||
|
||||
/** \returns the minimum of all coefficients of \c *this.
|
||||
* 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.
|
||||
* \warning the result is undefined if \c *this contains NaN.
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<int NaNPropagation>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
||||
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.
|
||||
* 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.
|
||||
* \warning the result is undefined if \c *this contains NaN.
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<int NaNPropagation>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
||||
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
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#ifndef EIGEN_REF_H
|
||||
#define EIGEN_REF_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
@@ -48,7 +48,7 @@ struct traits<Ref<_PlainObjectType, _Options, _StrideType> >
|
||||
};
|
||||
typedef typename internal::conditional<MatchAtCompileTime,internal::true_type,internal::false_type>::type type;
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
@@ -67,12 +67,12 @@ public:
|
||||
typedef MapBase<Derived> Base;
|
||||
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;
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC inline Index outerStride() const
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index outerStride() const
|
||||
{
|
||||
return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
|
||||
: IsVectorAtCompileTime ? this->size()
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
m_stride(StrideType::OuterStrideAtCompileTime==Dynamic?0:StrideType::OuterStrideAtCompileTime,
|
||||
StrideType::InnerStrideAtCompileTime==Dynamic?0:StrideType::InnerStrideAtCompileTime)
|
||||
{}
|
||||
|
||||
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(RefBase)
|
||||
|
||||
protected:
|
||||
@@ -94,25 +94,13 @@ protected:
|
||||
typedef Stride<StrideType::OuterStrideAtCompileTime,StrideType::InnerStrideAtCompileTime> StrideBase;
|
||||
|
||||
// Resolves inner stride if default 0.
|
||||
static EIGEN_DEVICE_FUNC Index resolveInnerStride(Index inner) {
|
||||
if (inner == 0) {
|
||||
return 1;
|
||||
}
|
||||
return inner;
|
||||
static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index resolveInnerStride(Index inner) {
|
||||
return inner == 0 ? 1 : inner;
|
||||
}
|
||||
|
||||
|
||||
// Resolves outer stride if default 0.
|
||||
static EIGEN_DEVICE_FUNC Index resolveOuterStride(Index inner, Index outer, Index rows, Index cols, bool isVectorAtCompileTime, bool isRowMajor) {
|
||||
if (outer == 0) {
|
||||
if (isVectorAtCompileTime) {
|
||||
outer = inner * rows * cols;
|
||||
} else if (isRowMajor) {
|
||||
outer = inner * cols;
|
||||
} else {
|
||||
outer = inner * rows;
|
||||
}
|
||||
}
|
||||
return outer;
|
||||
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,
|
||||
@@ -155,8 +143,8 @@ protected:
|
||||
(PlainObjectType::RowsAtCompileTime == Dynamic) || (PlainObjectType::RowsAtCompileTime == rows));
|
||||
eigen_assert(
|
||||
(PlainObjectType::ColsAtCompileTime == Dynamic) || (PlainObjectType::ColsAtCompileTime == cols));
|
||||
|
||||
|
||||
|
||||
|
||||
// If this is a vector, we might be transposing, which means that stride should swap.
|
||||
const bool transpose = PlainObjectType::IsVectorAtCompileTime && (rows != expr.rows());
|
||||
// If the storage format differs, we also need to swap the stride.
|
||||
@@ -165,42 +153,42 @@ protected:
|
||||
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,
|
||||
const Index expr_outer_actual = resolveOuterStride(expr_inner_actual,
|
||||
expr.outerStride(),
|
||||
expr.rows(),
|
||||
expr.cols(),
|
||||
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)
|
||||
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)
|
||||
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,
|
||||
inner_stride,
|
||||
Index(StrideType::OuterStrideAtCompileTime),
|
||||
rows, cols, PlainObjectType::IsVectorAtCompileTime != 0,
|
||||
row_major)
|
||||
@@ -208,7 +196,7 @@ protected:
|
||||
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,
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#ifndef EIGEN_REPLICATE_H
|
||||
#define EIGEN_REPLICATE_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
template<typename MatrixType,int RowFactor,int ColFactor>
|
||||
@@ -35,7 +35,7 @@ struct traits<Replicate<MatrixType,RowFactor,ColFactor> >
|
||||
IsRowMajor = MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1 ? 1
|
||||
: MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1 ? 0
|
||||
: (MatrixType::Flags & RowMajorBit) ? 1 : 0,
|
||||
|
||||
|
||||
// FIXME enable DirectAccess with negative strides?
|
||||
Flags = IsRowMajor ? RowMajorBit : 0
|
||||
};
|
||||
@@ -88,15 +88,15 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
|
||||
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(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index cols() const { return m_matrix.cols() * m_colFactor.value(); }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
const _MatrixTypeNested& nestedExpression() const
|
||||
{
|
||||
return m_matrix;
|
||||
{
|
||||
return m_matrix;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
@@ -240,14 +240,14 @@ class ReshapedImpl_dense<XprType, Rows, Cols, Order, true>
|
||||
XprType& nestedExpression() { return m_xpr; }
|
||||
|
||||
/** \sa MapBase::innerStride() */
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index innerStride() const
|
||||
{
|
||||
return m_xpr.innerStride();
|
||||
}
|
||||
|
||||
/** \sa MapBase::outerStride() */
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index outerStride() const
|
||||
{
|
||||
return ((Flags&RowMajorBit)==RowMajorBit) ? this->cols() : this->rows();
|
||||
|
||||
@@ -60,8 +60,10 @@ template<typename Derived> class ReturnByValue
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline void evalTo(Dest& dst) const
|
||||
{ static_cast<const Derived*>(this)->evalTo(dst); }
|
||||
EIGEN_DEVICE_FUNC inline Index rows() const { return static_cast<const Derived*>(this)->rows(); }
|
||||
EIGEN_DEVICE_FUNC inline Index cols() const { return static_cast<const Derived*>(this)->cols(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
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
|
||||
#define Unusable YOU_ARE_TRYING_TO_ACCESS_A_SINGLE_COEFFICIENT_IN_A_SPECIAL_EXPRESSION_WHERE_THAT_IS_NOT_ALLOWED_BECAUSE_THAT_WOULD_BE_INEFFICIENT
|
||||
@@ -90,7 +92,7 @@ namespace internal {
|
||||
// Expression is evaluated in a temporary; default implementation of Assignment is bypassed so that
|
||||
// when a ReturnByValue expression is assigned, the evaluator is not constructed.
|
||||
// TODO: Finalize port to new regime; ReturnByValue should not exist in the expression world
|
||||
|
||||
|
||||
template<typename Derived>
|
||||
struct evaluator<ReturnByValue<Derived> >
|
||||
: public evaluator<typename internal::traits<Derived>::ReturnType>
|
||||
@@ -98,7 +100,7 @@ struct evaluator<ReturnByValue<Derived> >
|
||||
typedef ReturnByValue<Derived> XprType;
|
||||
typedef typename internal::traits<Derived>::ReturnType PlainObject;
|
||||
typedef evaluator<PlainObject> Base;
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr)
|
||||
: m_result(xpr.rows(), xpr.cols())
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#ifndef EIGEN_REVERSE_H
|
||||
#define EIGEN_REVERSE_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
@@ -44,7 +44,7 @@ template<typename PacketType> struct reverse_packet_cond<PacketType,false>
|
||||
static inline PacketType run(const PacketType& x) { return x; }
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
} // end namespace internal
|
||||
|
||||
/** \class Reverse
|
||||
* \ingroup Core_Module
|
||||
@@ -89,8 +89,10 @@ template<typename MatrixType, int Direction> class Reverse
|
||||
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reverse)
|
||||
|
||||
EIGEN_DEVICE_FUNC inline Index rows() const { return m_matrix.rows(); }
|
||||
EIGEN_DEVICE_FUNC inline Index cols() const { return m_matrix.cols(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
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
|
||||
{
|
||||
@@ -98,7 +100,7 @@ template<typename MatrixType, int Direction> class Reverse
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC const typename internal::remove_all<typename MatrixType::Nested>::type&
|
||||
nestedExpression() const
|
||||
nestedExpression() const
|
||||
{
|
||||
return m_matrix;
|
||||
}
|
||||
@@ -161,7 +163,7 @@ EIGEN_DEVICE_FUNC inline void DenseBase<Derived>::reverseInPlace()
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
|
||||
template<int Direction>
|
||||
struct vectorwise_reverse_inplace_impl;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#ifndef EIGEN_SELECT_H
|
||||
#define EIGEN_SELECT_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
/** \class Select
|
||||
* \ingroup Core_Module
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
inline EIGEN_DEVICE_FUNC Index rows() const { return m_condition.rows(); }
|
||||
inline EIGEN_DEVICE_FUNC Index cols() const { return m_condition.cols(); }
|
||||
inline EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
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
|
||||
const Scalar coeff(Index i, Index j) const
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#ifndef EIGEN_SELFADJOINTMATRIX_H
|
||||
#define EIGEN_SELFADJOINTMATRIX_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
/** \class SelfAdjointView
|
||||
* \ingroup Core_Module
|
||||
@@ -58,7 +58,7 @@ template<typename _MatrixType, unsigned int UpLo> class SelfAdjointView
|
||||
typedef MatrixTypeNestedCleaned NestedExpression;
|
||||
|
||||
/** \brief The type of coefficients in this matrix */
|
||||
typedef typename internal::traits<SelfAdjointView>::Scalar Scalar;
|
||||
typedef typename internal::traits<SelfAdjointView>::Scalar Scalar;
|
||||
typedef typename MatrixType::StorageIndex StorageIndex;
|
||||
typedef typename internal::remove_all<typename MatrixType::ConjugateReturnType>::type MatrixConjugateReturnType;
|
||||
typedef SelfAdjointView<typename internal::add_const<MatrixType>::type, UpLo> ConstSelfAdjointView;
|
||||
@@ -76,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_DEVICE_FUNC
|
||||
inline Index rows() const { return m_matrix.rows(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index cols() const { return m_matrix.cols(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index outerStride() const { return m_matrix.outerStride(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index innerStride() const { return m_matrix.innerStride(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
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 EIGEN_CONSTEXPR
|
||||
inline Index outerStride() const EIGEN_NOEXCEPT { return m_matrix.outerStride(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index innerStride() const EIGEN_NOEXCEPT { return m_matrix.innerStride(); }
|
||||
|
||||
/** \sa MatrixBase::coeff()
|
||||
* \warning the coordinates must fit into the referenced triangular part
|
||||
@@ -132,7 +132,7 @@ template<typename _MatrixType, unsigned int UpLo> class SelfAdjointView
|
||||
{
|
||||
return Product<OtherDerived,SelfAdjointView>(lhs.derived(),rhs);
|
||||
}
|
||||
|
||||
|
||||
friend EIGEN_DEVICE_FUNC
|
||||
const SelfAdjointView<const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar,MatrixType,product),UpLo>
|
||||
operator*(const Scalar& s, const SelfAdjointView& mat)
|
||||
@@ -300,17 +300,17 @@ protected:
|
||||
using Base::m_src;
|
||||
using Base::m_functor;
|
||||
public:
|
||||
|
||||
|
||||
typedef typename Base::DstEvaluatorType DstEvaluatorType;
|
||||
typedef typename Base::SrcEvaluatorType SrcEvaluatorType;
|
||||
typedef typename Base::Scalar Scalar;
|
||||
typedef typename Base::AssignmentTraits AssignmentTraits;
|
||||
|
||||
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC triangular_dense_assignment_kernel(DstEvaluatorType &dst, const SrcEvaluatorType &src, const Functor &func, DstXprType& dstExpr)
|
||||
: Base(dst, src, func, dstExpr)
|
||||
{}
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC void assignCoeff(Index row, Index col)
|
||||
{
|
||||
eigen_internal_assert(row!=col);
|
||||
@@ -318,12 +318,12 @@ public:
|
||||
m_functor.assignCoeff(m_dst.coeffRef(row,col), tmp);
|
||||
m_functor.assignCoeff(m_dst.coeffRef(col,row), numext::conj(tmp));
|
||||
}
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC void assignDiagonalCoeff(Index id)
|
||||
{
|
||||
Base::assignCoeff(id,id);
|
||||
}
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC void assignOppositeCoeff(Index, Index)
|
||||
{ eigen_internal_assert(false && "should never be called"); }
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
namespace Eigen {
|
||||
|
||||
template<typename Decomposition, typename RhsType, typename StorageKind> class SolveImpl;
|
||||
|
||||
|
||||
/** \class Solve
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
@@ -64,13 +64,13 @@ class Solve : public SolveImpl<Decomposition,RhsType,typename internal::traits<R
|
||||
public:
|
||||
typedef typename internal::traits<Solve>::PlainObject PlainObject;
|
||||
typedef typename internal::traits<Solve>::StorageIndex StorageIndex;
|
||||
|
||||
|
||||
Solve(const Decomposition &dec, const RhsType &rhs)
|
||||
: m_dec(dec), m_rhs(rhs)
|
||||
{}
|
||||
|
||||
EIGEN_DEVICE_FUNC Index rows() const { return m_dec.cols(); }
|
||||
EIGEN_DEVICE_FUNC Index cols() const { return m_rhs.cols(); }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_dec.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 RhsType& rhs() const { return m_rhs; }
|
||||
@@ -87,14 +87,14 @@ class SolveImpl<Decomposition,RhsType,Dense>
|
||||
: public MatrixBase<Solve<Decomposition,RhsType> >
|
||||
{
|
||||
typedef Solve<Decomposition,RhsType> Derived;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
typedef MatrixBase<Solve<Decomposition,RhsType> > Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
|
||||
|
||||
private:
|
||||
|
||||
|
||||
Scalar coeff(Index row, Index col) const;
|
||||
Scalar coeff(Index i) const;
|
||||
};
|
||||
@@ -119,15 +119,15 @@ struct evaluator<Solve<Decomposition,RhsType> >
|
||||
typedef evaluator<PlainObject> Base;
|
||||
|
||||
enum { Flags = Base::Flags | EvalBeforeNestingBit };
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC explicit evaluator(const SolveType& solve)
|
||||
: m_result(solve.rows(), solve.cols())
|
||||
{
|
||||
::new (static_cast<Base*>(this)) Base(m_result);
|
||||
solve.dec()._solve_impl(solve.rhs(), m_result);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
protected:
|
||||
PlainObject m_result;
|
||||
};
|
||||
|
||||
@@ -176,7 +176,7 @@ struct Assignment<DstXprType, Solve<CwiseUnaryOp<internal::scalar_conjugate_op<t
|
||||
Index dstCols = src.cols();
|
||||
if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
|
||||
dst.resize(dstRows, dstCols);
|
||||
|
||||
|
||||
src.dec().nestedExpression().nestedExpression().template _solve_impl_transposed<true>(src.rhs(), dst);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -213,8 +213,8 @@ template<int Side, typename TriangularType, typename Rhs> struct triangular_solv
|
||||
: m_triangularMatrix(tri), m_rhs(rhs)
|
||||
{}
|
||||
|
||||
inline Index rows() const { return m_rhs.rows(); }
|
||||
inline Index cols() const { return m_rhs.cols(); }
|
||||
inline EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_rhs.rows(); }
|
||||
inline EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_rhs.cols(); }
|
||||
|
||||
template<typename Dest> inline void evalTo(Dest& dst) const
|
||||
{
|
||||
|
||||
@@ -10,10 +10,6 @@
|
||||
#ifndef EIGEN_STABLENORM_H
|
||||
#define EIGEN_STABLENORM_H
|
||||
|
||||
#if EIGEN_HAS_CXX11_ATOMIC
|
||||
#include <atomic>
|
||||
#endif
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
@@ -138,9 +134,9 @@ blueNorm_impl(const EigenBase<Derived>& _vec)
|
||||
// statements can be replaced
|
||||
static const int ibeta = std::numeric_limits<RealScalar>::radix; // base for floating-point numbers
|
||||
static const int it = NumTraits<RealScalar>::digits(); // number of base-beta digits in mantissa
|
||||
static const int iemin = std::numeric_limits<RealScalar>::min_exponent; // minimum exponent
|
||||
static const int iemax = std::numeric_limits<RealScalar>::max_exponent; // maximum exponent
|
||||
static const RealScalar rbig = (std::numeric_limits<RealScalar>::max)(); // largest floating-point number
|
||||
static const int iemin = NumTraits<RealScalar>::min_exponent(); // minimum exponent
|
||||
static const int iemax = NumTraits<RealScalar>::max_exponent(); // maximum exponent
|
||||
static const RealScalar rbig = NumTraits<RealScalar>::highest(); // largest floating-point number
|
||||
static const RealScalar b1 = RealScalar(pow(RealScalar(ibeta),RealScalar(-((1-iemin)/2)))); // lower boundary of midrange
|
||||
static const RealScalar b2 = RealScalar(pow(RealScalar(ibeta),RealScalar((iemax + 1 - it)/2))); // upper boundary of midrange
|
||||
static const RealScalar s1m = RealScalar(pow(RealScalar(ibeta),RealScalar((2-iemin)/2))); // scaling factor for lower range
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#ifndef EIGEN_STRIDE_H
|
||||
#define EIGEN_STRIDE_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
/** \class Stride
|
||||
* \ingroup Core_Module
|
||||
@@ -26,7 +26,7 @@ namespace Eigen {
|
||||
*
|
||||
* The outer stride is the pointer increment between two consecutive rows of a row-major matrix or
|
||||
* between two consecutive columns of a column-major matrix.
|
||||
*
|
||||
*
|
||||
* These two values can be passed either at compile-time as template parameters, or at runtime as
|
||||
* arguments to the constructor.
|
||||
*
|
||||
@@ -41,7 +41,7 @@ namespace Eigen {
|
||||
* 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
|
||||
*/
|
||||
template<int _OuterStrideAtCompileTime, int _InnerStrideAtCompileTime>
|
||||
@@ -78,10 +78,10 @@ class Stride
|
||||
{}
|
||||
|
||||
/** \returns the outer stride */
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index outer() const { return m_outer.value(); }
|
||||
/** \returns the inner stride */
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index inner() const { return m_inner.value(); }
|
||||
|
||||
protected:
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#ifndef EIGEN_TRANSPOSE_H
|
||||
#define EIGEN_TRANSPOSE_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
template<typename MatrixType>
|
||||
@@ -65,10 +65,10 @@ template<typename MatrixType> class Transpose
|
||||
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Transpose)
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
Index rows() const { return m_matrix.cols(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
Index cols() const { return m_matrix.rows(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
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 */
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
@@ -336,7 +336,7 @@ struct inplace_transpose_selector<MatrixType,false,MatchPacketSize> { // non squ
|
||||
* Notice however that this method is only useful if you want to replace a matrix by its own transpose.
|
||||
* If you just need the transpose of a matrix, use transpose().
|
||||
*
|
||||
* \note if the matrix is not square, then \c *this must be a resizable matrix.
|
||||
* \note if the matrix is not square, then \c *this must be a resizable matrix.
|
||||
* This excludes (non-square) fixed-size matrices, block-expressions and maps.
|
||||
*
|
||||
* \sa transpose(), adjoint(), adjointInPlace() */
|
||||
|
||||
@@ -349,12 +349,12 @@ class Transpose<TranspositionsBase<TranspositionsDerived> >
|
||||
|
||||
explicit Transpose(const TranspositionType& t) : m_transpositions(t) {}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
Index size() const { return m_transpositions.size(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
Index rows() const { return m_transpositions.size(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
Index cols() const { return m_transpositions.size(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
Index size() const EIGEN_NOEXCEPT { 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.
|
||||
*/
|
||||
|
||||
@@ -11,12 +11,12 @@
|
||||
#ifndef EIGEN_TRIANGULARMATRIX_H
|
||||
#define EIGEN_TRIANGULARMATRIX_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
|
||||
template<int Side, typename TriangularType, typename Rhs> struct triangular_solve_retval;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/** \class TriangularBase
|
||||
@@ -34,16 +34,16 @@ template<typename Derived> class TriangularBase : public EigenBase<Derived>
|
||||
ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
|
||||
MaxRowsAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime,
|
||||
MaxColsAtCompileTime = internal::traits<Derived>::MaxColsAtCompileTime,
|
||||
|
||||
|
||||
SizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::RowsAtCompileTime,
|
||||
internal::traits<Derived>::ColsAtCompileTime>::ret),
|
||||
/**< This is equal to the number of coefficients, i.e. the number of
|
||||
* rows times the number of columns, or to \a Dynamic if this is not
|
||||
* known at compile-time. \sa RowsAtCompileTime, ColsAtCompileTime */
|
||||
|
||||
|
||||
MaxSizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::MaxRowsAtCompileTime,
|
||||
internal::traits<Derived>::MaxColsAtCompileTime>::ret)
|
||||
|
||||
|
||||
};
|
||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
||||
@@ -55,15 +55,15 @@ template<typename Derived> class TriangularBase : public EigenBase<Derived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline TriangularBase() { eigen_assert(!((Mode&UnitDiag) && (Mode&ZeroDiag))); }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index rows() const { return derived().rows(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index cols() const { return derived().cols(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index outerStride() const { return derived().outerStride(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index innerStride() const { return derived().innerStride(); }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index rows() const EIGEN_NOEXCEPT { return derived().rows(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index cols() const EIGEN_NOEXCEPT { return derived().cols(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index outerStride() const EIGEN_NOEXCEPT { return derived().outerStride(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index innerStride() const EIGEN_NOEXCEPT { return derived().innerStride(); }
|
||||
|
||||
// dummy resize function
|
||||
EIGEN_DEVICE_FUNC
|
||||
void resize(Index rows, Index cols)
|
||||
@@ -156,7 +156,7 @@ template<typename Derived> class TriangularBase : public EigenBase<Derived>
|
||||
* \param MatrixType the type of the object in which we are taking the triangular part
|
||||
* \param Mode the kind of triangular matrix expression to construct. Can be #Upper,
|
||||
* #Lower, #UnitUpper, #UnitLower, #StrictlyUpper, or #StrictlyLower.
|
||||
* This is in fact a bit field; it must have either #Upper or #Lower,
|
||||
* This is in fact a bit field; it must have either #Upper or #Lower,
|
||||
* and additionally it may have #UnitDiag or #ZeroDiag or neither.
|
||||
*
|
||||
* This class represents a triangular part of a matrix, not necessarily square. Strictly speaking, for rectangular
|
||||
@@ -199,7 +199,7 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
|
||||
|
||||
typedef typename internal::remove_all<typename MatrixType::ConjugateReturnType>::type MatrixConjugateReturnType;
|
||||
typedef TriangularView<typename internal::add_const<MatrixType>::type, _Mode> ConstTriangularView;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
typedef typename internal::traits<TriangularView>::StorageKind StorageKind;
|
||||
@@ -218,15 +218,15 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit inline TriangularView(MatrixType& matrix) : m_matrix(matrix)
|
||||
{}
|
||||
|
||||
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TriangularView)
|
||||
|
||||
/** \copydoc EigenBase::rows() */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index rows() const { return m_matrix.rows(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index rows() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
|
||||
/** \copydoc EigenBase::cols() */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index cols() const { return m_matrix.cols(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
|
||||
|
||||
/** \returns a const reference to the nested expression */
|
||||
EIGEN_DEVICE_FUNC
|
||||
@@ -235,7 +235,7 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
|
||||
/** \returns a reference to the nested expression */
|
||||
EIGEN_DEVICE_FUNC
|
||||
NestedExpression& nestedExpression() { return m_matrix; }
|
||||
|
||||
|
||||
typedef TriangularView<const MatrixConjugateReturnType,Mode> ConjugateReturnType;
|
||||
/** \sa MatrixBase::conjugate() const */
|
||||
EIGEN_DEVICE_FUNC
|
||||
@@ -269,7 +269,7 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
|
||||
typename MatrixType::TransposeReturnType tmp(m_matrix);
|
||||
return TransposeReturnType(tmp);
|
||||
}
|
||||
|
||||
|
||||
typedef TriangularView<const typename MatrixType::ConstTransposeReturnType,TransposeMode> ConstTransposeReturnType;
|
||||
/** \sa MatrixBase::transpose() const */
|
||||
EIGEN_DEVICE_FUNC
|
||||
@@ -280,10 +280,10 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
|
||||
|
||||
template<typename Other>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Solve<TriangularView, Other>
|
||||
inline const Solve<TriangularView, Other>
|
||||
solve(const MatrixBase<Other>& other) const
|
||||
{ return Solve<TriangularView, Other>(*this, other.derived()); }
|
||||
|
||||
|
||||
// workaround MSVC ICE
|
||||
#if EIGEN_COMP_MSVC
|
||||
template<int Side, typename Other>
|
||||
@@ -327,7 +327,7 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
|
||||
else
|
||||
return m_matrix.diagonal().prod();
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
MatrixTypeNested m_matrix;
|
||||
@@ -389,7 +389,7 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
||||
internal::call_assignment_no_alias(derived(), other.derived(), internal::sub_assign_op<Scalar,typename Other::Scalar>());
|
||||
return derived();
|
||||
}
|
||||
|
||||
|
||||
/** \sa MatrixBase::operator*=() */
|
||||
EIGEN_DEVICE_FUNC
|
||||
TriangularViewType& operator*=(const typename internal::traits<MatrixType>::Scalar& other) { return *this = derived().nestedExpression() * other; }
|
||||
@@ -715,7 +715,7 @@ bool MatrixBase<Derived>::isLowerTriangular(const RealScalar& prec) const
|
||||
|
||||
namespace internal {
|
||||
|
||||
|
||||
|
||||
// TODO currently a triangular expression has the form TriangularView<.,.>
|
||||
// in the future triangular-ness should be defined by the expression traits
|
||||
// such that Transpose<TriangularView<.,.> > is valid. (currently TriangularBase::transpose() is overloaded to make it work)
|
||||
@@ -744,7 +744,7 @@ struct Dense2Triangular {};
|
||||
|
||||
template<typename Kernel, unsigned int Mode, int UnrollCount, bool ClearOpposite> struct triangular_assignment_loop;
|
||||
|
||||
|
||||
|
||||
/** \internal Specialization of the dense assignment kernel for triangular matrices.
|
||||
* The main difference is that the triangular, diagonal, and opposite parts are processed through three different functions.
|
||||
* \tparam UpLo must be either Lower or Upper
|
||||
@@ -761,17 +761,17 @@ protected:
|
||||
using Base::m_src;
|
||||
using Base::m_functor;
|
||||
public:
|
||||
|
||||
|
||||
typedef typename Base::DstEvaluatorType DstEvaluatorType;
|
||||
typedef typename Base::SrcEvaluatorType SrcEvaluatorType;
|
||||
typedef typename Base::Scalar Scalar;
|
||||
typedef typename Base::AssignmentTraits AssignmentTraits;
|
||||
|
||||
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC triangular_dense_assignment_kernel(DstEvaluatorType &dst, const SrcEvaluatorType &src, const Functor &func, DstXprType& dstExpr)
|
||||
: Base(dst, src, func, dstExpr)
|
||||
{}
|
||||
|
||||
|
||||
#ifdef EIGEN_INTERNAL_DEBUGGING
|
||||
EIGEN_DEVICE_FUNC void assignCoeff(Index row, Index col)
|
||||
{
|
||||
@@ -781,16 +781,16 @@ public:
|
||||
#else
|
||||
using Base::assignCoeff;
|
||||
#endif
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC void assignDiagonalCoeff(Index id)
|
||||
{
|
||||
if(Mode==UnitDiag && SetOpposite) m_functor.assignCoeff(m_dst.coeffRef(id,id), Scalar(1));
|
||||
else if(Mode==ZeroDiag && SetOpposite) m_functor.assignCoeff(m_dst.coeffRef(id,id), Scalar(0));
|
||||
else if(Mode==0) Base::assignCoeff(id,id);
|
||||
}
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC void assignOppositeCoeff(Index row, Index col)
|
||||
{
|
||||
{
|
||||
eigen_internal_assert(row!=col);
|
||||
if(SetOpposite)
|
||||
m_functor.assignCoeff(m_dst.coeffRef(row,col), Scalar(0));
|
||||
@@ -811,17 +811,17 @@ void call_triangular_assignment_loop(DstXprType& dst, const SrcXprType& src, con
|
||||
if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
|
||||
dst.resize(dstRows, dstCols);
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
|
||||
|
||||
typedef triangular_dense_assignment_kernel< Mode&(Lower|Upper),Mode&(UnitDiag|ZeroDiag|SelfAdjoint),SetOpposite,
|
||||
DstEvaluatorType,SrcEvaluatorType,Functor> Kernel;
|
||||
Kernel kernel(dstEvaluator, srcEvaluator, func, dst.const_cast_derived());
|
||||
|
||||
|
||||
enum {
|
||||
unroll = DstXprType::SizeAtCompileTime != Dynamic
|
||||
&& SrcEvaluatorType::CoeffReadCost < HugeCost
|
||||
&& DstXprType::SizeAtCompileTime * (DstEvaluatorType::CoeffReadCost+SrcEvaluatorType::CoeffReadCost) / 2 <= EIGEN_UNROLLING_LIMIT
|
||||
};
|
||||
|
||||
|
||||
triangular_assignment_loop<Kernel, Mode, unroll ? int(DstXprType::SizeAtCompileTime) : Dynamic, SetOpposite>::run(kernel);
|
||||
}
|
||||
|
||||
@@ -843,8 +843,8 @@ struct Assignment<DstXprType, SrcXprType, Functor, Triangular2Triangular>
|
||||
EIGEN_DEVICE_FUNC static void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
|
||||
{
|
||||
eigen_assert(int(DstXprType::Mode) == int(SrcXprType::Mode));
|
||||
|
||||
call_triangular_assignment_loop<DstXprType::Mode, false>(dst, src, func);
|
||||
|
||||
call_triangular_assignment_loop<DstXprType::Mode, false>(dst, src, func);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -853,7 +853,7 @@ struct Assignment<DstXprType, SrcXprType, Functor, Triangular2Dense>
|
||||
{
|
||||
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, (SrcXprType::Mode&SelfAdjoint)==0>(dst, src, func);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -862,7 +862,7 @@ struct Assignment<DstXprType, SrcXprType, Functor, Dense2Triangular>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC static void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
|
||||
{
|
||||
call_triangular_assignment_loop<DstXprType::Mode, false>(dst, src, func);
|
||||
call_triangular_assignment_loop<DstXprType::Mode, false>(dst, src, func);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -873,19 +873,19 @@ struct triangular_assignment_loop
|
||||
// FIXME: this is not very clean, perhaps this information should be provided by the kernel?
|
||||
typedef typename Kernel::DstEvaluatorType DstEvaluatorType;
|
||||
typedef typename DstEvaluatorType::XprType DstXprType;
|
||||
|
||||
|
||||
enum {
|
||||
col = (UnrollCount-1) / DstXprType::RowsAtCompileTime,
|
||||
row = (UnrollCount-1) % DstXprType::RowsAtCompileTime
|
||||
};
|
||||
|
||||
|
||||
typedef typename Kernel::Scalar Scalar;
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline void run(Kernel &kernel)
|
||||
{
|
||||
triangular_assignment_loop<Kernel, Mode, UnrollCount-1, SetOpposite>::run(kernel);
|
||||
|
||||
|
||||
if(row==col)
|
||||
kernel.assignDiagonalCoeff(row);
|
||||
else if( ((Mode&Lower) && row>col) || ((Mode&Upper) && row<col) )
|
||||
@@ -928,10 +928,10 @@ struct triangular_assignment_loop<Kernel, Mode, Dynamic, SetOpposite>
|
||||
}
|
||||
else
|
||||
i = maxi;
|
||||
|
||||
|
||||
if(i<kernel.rows()) // then i==j
|
||||
kernel.assignDiagonalCoeff(i++);
|
||||
|
||||
|
||||
if (((Mode&Upper) && SetOpposite) || (Mode&Lower))
|
||||
{
|
||||
for(; i < kernel.rows(); ++i)
|
||||
@@ -955,7 +955,7 @@ EIGEN_DEVICE_FUNC void TriangularBase<Derived>::evalToLazy(MatrixBase<DenseDeriv
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
|
||||
// Triangular = Product
|
||||
template< typename DstXprType, typename Lhs, typename Rhs, typename Scalar>
|
||||
struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
|
||||
@@ -968,7 +968,7 @@ struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::assign_
|
||||
if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
|
||||
dst.resize(dstRows, dstCols);
|
||||
|
||||
dst._assignProduct(src, 1, 0);
|
||||
dst._assignProduct(src, Scalar(1), false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -979,7 +979,7 @@ struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::add_ass
|
||||
typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -990,7 +990,7 @@ struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::sub_ass
|
||||
typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -65,10 +65,10 @@ class PartialReduxExpr : public internal::dense_xpr_base< PartialReduxExpr<Matri
|
||||
explicit PartialReduxExpr(const MatrixType& mat, const MemberOp& func = MemberOp())
|
||||
: m_matrix(mat), m_functor(func) {}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
Index rows() const { return (Direction==Vertical ? 1 : m_matrix.rows()); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
Index cols() const { return (Direction==Horizontal ? 1 : m_matrix.cols()); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
Index rows() const EIGEN_NOEXCEPT { return (Direction==Vertical ? 1 : m_matrix.rows()); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
Index cols() const EIGEN_NOEXCEPT { return (Direction==Horizontal ? 1 : m_matrix.cols()); }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
typename MatrixType::Nested nestedExpression() const { return m_matrix; }
|
||||
@@ -134,7 +134,7 @@ struct member_redux {
|
||||
typedef typename result_of<
|
||||
BinaryOp(const Scalar&,const Scalar&)
|
||||
>::type result_type;
|
||||
|
||||
|
||||
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) {}
|
||||
@@ -162,17 +162,17 @@ struct member_redux {
|
||||
* 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
|
||||
* 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.
|
||||
@@ -180,7 +180,7 @@ struct member_redux {
|
||||
* - 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
|
||||
*/
|
||||
template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
@@ -216,7 +216,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
template<typename OtherDerived> struct ExtendedType {
|
||||
typedef Replicate<OtherDerived,
|
||||
isVertical ? 1 : ExpressionType::RowsAtCompileTime,
|
||||
@@ -328,7 +328,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
*
|
||||
* \warning the size along the reduction direction must be strictly positive,
|
||||
* otherwise an assertion is triggered.
|
||||
*
|
||||
*
|
||||
* \sa class VectorwiseOp, DenseBase::colwise(), DenseBase::rowwise()
|
||||
*/
|
||||
template<typename BinaryOp>
|
||||
@@ -365,7 +365,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
*
|
||||
* \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.
|
||||
*
|
||||
* Example: \include PartialRedux_minCoeff.cpp
|
||||
@@ -384,7 +384,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
*
|
||||
* \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.
|
||||
*
|
||||
* Example: \include PartialRedux_maxCoeff.cpp
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#ifndef EIGEN_VISITOR_H
|
||||
#define EIGEN_VISITOR_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
@@ -70,22 +70,22 @@ class visitor_evaluator
|
||||
public:
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit visitor_evaluator(const XprType &xpr) : m_evaluator(xpr), m_xpr(xpr) {}
|
||||
|
||||
|
||||
typedef typename XprType::Scalar Scalar;
|
||||
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
||||
|
||||
|
||||
enum {
|
||||
RowsAtCompileTime = XprType::RowsAtCompileTime,
|
||||
CoeffReadCost = internal::evaluator<XprType>::CoeffReadCost
|
||||
};
|
||||
|
||||
EIGEN_DEVICE_FUNC Index rows() const { return m_xpr.rows(); }
|
||||
EIGEN_DEVICE_FUNC Index cols() const { return m_xpr.cols(); }
|
||||
EIGEN_DEVICE_FUNC Index size() const { return m_xpr.size(); }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_xpr.rows(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_xpr.cols(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index size() const EIGEN_NOEXCEPT { return m_xpr.size(); }
|
||||
|
||||
EIGEN_DEVICE_FUNC CoeffReturnType coeff(Index row, Index col) const
|
||||
{ return m_evaluator.coeff(row, col); }
|
||||
|
||||
|
||||
protected:
|
||||
internal::evaluator<XprType> m_evaluator;
|
||||
const XprType &m_xpr;
|
||||
@@ -106,7 +106,7 @@ protected:
|
||||
*
|
||||
* \note compared to one or two \em for \em loops, visitors offer automatic
|
||||
* unrolling for small fixed size matrix.
|
||||
*
|
||||
*
|
||||
* \note if the matrix is empty, then the visitor is left unchanged.
|
||||
*
|
||||
* \sa minCoeff(Index*,Index*), maxCoeff(Index*,Index*), DenseBase::redux()
|
||||
@@ -118,10 +118,10 @@ void DenseBase<Derived>::visit(Visitor& visitor) const
|
||||
{
|
||||
if(size()==0)
|
||||
return;
|
||||
|
||||
|
||||
typedef typename internal::visitor_evaluator<Derived> ThisEvaluator;
|
||||
ThisEvaluator thisEval(derived());
|
||||
|
||||
|
||||
enum {
|
||||
unroll = SizeAtCompileTime != Dynamic
|
||||
&& SizeAtCompileTime * ThisEvaluator::CoeffReadCost + (SizeAtCompileTime-1) * internal::functor_traits<Visitor>::Cost <= EIGEN_UNROLLING_LIMIT
|
||||
@@ -157,7 +157,7 @@ struct coeff_visitor
|
||||
*
|
||||
* \sa DenseBase::minCoeff(Index*, Index*)
|
||||
*/
|
||||
template <typename Derived>
|
||||
template <typename Derived, int NaNPropagation>
|
||||
struct min_coeff_visitor : coeff_visitor<Derived>
|
||||
{
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
@@ -173,8 +173,40 @@ struct min_coeff_visitor : coeff_visitor<Derived>
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Scalar>
|
||||
struct functor_traits<min_coeff_visitor<Scalar> > {
|
||||
template <typename Derived>
|
||||
struct min_coeff_visitor<Derived, PropagateNumbers> : coeff_visitor<Derived>
|
||||
{
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
EIGEN_DEVICE_FUNC
|
||||
void operator() (const Scalar& value, Index i, Index j)
|
||||
{
|
||||
if((numext::isnan)(this->res) || (!(numext::isnan)(value) && value < this->res))
|
||||
{
|
||||
this->res = value;
|
||||
this->row = i;
|
||||
this->col = j;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Derived>
|
||||
struct min_coeff_visitor<Derived, PropagateNaN> : coeff_visitor<Derived>
|
||||
{
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
EIGEN_DEVICE_FUNC
|
||||
void operator() (const Scalar& value, Index i, Index j)
|
||||
{
|
||||
if((numext::isnan)(value) || value < this->res)
|
||||
{
|
||||
this->res = value;
|
||||
this->row = i;
|
||||
this->col = j;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Scalar, int NaNPropagation>
|
||||
struct functor_traits<min_coeff_visitor<Scalar, NaNPropagation> > {
|
||||
enum {
|
||||
Cost = NumTraits<Scalar>::AddCost
|
||||
};
|
||||
@@ -185,10 +217,10 @@ struct functor_traits<min_coeff_visitor<Scalar> > {
|
||||
*
|
||||
* \sa DenseBase::maxCoeff(Index*, Index*)
|
||||
*/
|
||||
template <typename Derived>
|
||||
template <typename Derived, int NaNPropagation>
|
||||
struct max_coeff_visitor : coeff_visitor<Derived>
|
||||
{
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
EIGEN_DEVICE_FUNC
|
||||
void operator() (const Scalar& value, Index i, Index j)
|
||||
{
|
||||
@@ -201,8 +233,40 @@ struct max_coeff_visitor : coeff_visitor<Derived>
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Scalar>
|
||||
struct functor_traits<max_coeff_visitor<Scalar> > {
|
||||
template <typename Derived>
|
||||
struct max_coeff_visitor<Derived, PropagateNumbers> : coeff_visitor<Derived>
|
||||
{
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
EIGEN_DEVICE_FUNC
|
||||
void operator() (const Scalar& value, Index i, Index j)
|
||||
{
|
||||
if((numext::isnan)(this->res) || (!(numext::isnan)(value) && value > this->res))
|
||||
{
|
||||
this->res = value;
|
||||
this->row = i;
|
||||
this->col = j;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Derived>
|
||||
struct max_coeff_visitor<Derived, PropagateNaN> : coeff_visitor<Derived>
|
||||
{
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
EIGEN_DEVICE_FUNC
|
||||
void operator() (const Scalar& value, Index i, Index j)
|
||||
{
|
||||
if((numext::isnan)(value) || value > this->res)
|
||||
{
|
||||
this->res = value;
|
||||
this->row = i;
|
||||
this->col = j;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Scalar, int NaNPropagation>
|
||||
struct functor_traits<max_coeff_visitor<Scalar, NaNPropagation> > {
|
||||
enum {
|
||||
Cost = NumTraits<Scalar>::AddCost
|
||||
};
|
||||
@@ -212,22 +276,24 @@ struct functor_traits<max_coeff_visitor<Scalar> > {
|
||||
|
||||
/** \fn DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
|
||||
* \returns the minimum of all coefficients of *this and puts in *row and *col its location.
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* \warning the result is undefined if \c *this contains NaN.
|
||||
*
|
||||
* \sa DenseBase::minCoeff(Index*), DenseBase::maxCoeff(Index*,Index*), DenseBase::visit(), DenseBase::minCoeff()
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename IndexType>
|
||||
template<int NaNPropagation, typename IndexType>
|
||||
EIGEN_DEVICE_FUNC
|
||||
typename internal::traits<Derived>::Scalar
|
||||
DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
|
||||
{
|
||||
eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
|
||||
|
||||
internal::min_coeff_visitor<Derived> minVisitor;
|
||||
internal::min_coeff_visitor<Derived, NaNPropagation> minVisitor;
|
||||
this->visit(minVisitor);
|
||||
*rowId = minVisitor.row;
|
||||
if (colId) *colId = minVisitor.col;
|
||||
@@ -235,15 +301,17 @@ DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
|
||||
}
|
||||
|
||||
/** \returns the minimum of all coefficients of *this and puts in *index its location.
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* \warning the result is undefined if \c *this contains NaN.
|
||||
*
|
||||
* \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::visit(), DenseBase::minCoeff()
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename IndexType>
|
||||
template<int NaNPropagation, typename IndexType>
|
||||
EIGEN_DEVICE_FUNC
|
||||
typename internal::traits<Derived>::Scalar
|
||||
DenseBase<Derived>::minCoeff(IndexType* index) const
|
||||
@@ -251,7 +319,7 @@ DenseBase<Derived>::minCoeff(IndexType* index) const
|
||||
eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
|
||||
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
internal::min_coeff_visitor<Derived> minVisitor;
|
||||
internal::min_coeff_visitor<Derived, NaNPropagation> minVisitor;
|
||||
this->visit(minVisitor);
|
||||
*index = IndexType((RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row);
|
||||
return minVisitor.res;
|
||||
@@ -259,22 +327,24 @@ DenseBase<Derived>::minCoeff(IndexType* index) const
|
||||
|
||||
/** \fn DenseBase<Derived>::maxCoeff(IndexType* rowId, IndexType* colId) const
|
||||
* \returns the maximum of all coefficients of *this and puts in *row and *col its location.
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* \warning the result is undefined if \c *this contains NaN.
|
||||
*
|
||||
* \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visit(), DenseBase::maxCoeff()
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename IndexType>
|
||||
template<int NaNPropagation, typename IndexType>
|
||||
EIGEN_DEVICE_FUNC
|
||||
typename internal::traits<Derived>::Scalar
|
||||
DenseBase<Derived>::maxCoeff(IndexType* rowPtr, IndexType* colPtr) const
|
||||
{
|
||||
eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
|
||||
|
||||
internal::max_coeff_visitor<Derived> maxVisitor;
|
||||
internal::max_coeff_visitor<Derived, NaNPropagation> maxVisitor;
|
||||
this->visit(maxVisitor);
|
||||
*rowPtr = maxVisitor.row;
|
||||
if (colPtr) *colPtr = maxVisitor.col;
|
||||
@@ -282,15 +352,17 @@ DenseBase<Derived>::maxCoeff(IndexType* rowPtr, IndexType* colPtr) const
|
||||
}
|
||||
|
||||
/** \returns the maximum of all coefficients of *this and puts in *index its location.
|
||||
*
|
||||
* \warning the matrix must be not empty, otherwise an assertion is triggered.
|
||||
*
|
||||
* \warning the result is undefined if \c *this contains NaN.
|
||||
* In case \c *this contains NaN, NaNPropagation determines the behavior:
|
||||
* NaNPropagation == PropagateFast : undefined
|
||||
* NaNPropagation == PropagateNaN : result is NaN
|
||||
* NaNPropagation == PropagateNumbers : result is maximum of elements that are not NaN
|
||||
* \warning the matrix must be not empty, otherwise an assertion is triggered.
|
||||
*
|
||||
* \sa DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visitor(), DenseBase::maxCoeff()
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename IndexType>
|
||||
template<int NaNPropagation, typename IndexType>
|
||||
EIGEN_DEVICE_FUNC
|
||||
typename internal::traits<Derived>::Scalar
|
||||
DenseBase<Derived>::maxCoeff(IndexType* index) const
|
||||
@@ -298,7 +370,7 @@ DenseBase<Derived>::maxCoeff(IndexType* index) const
|
||||
eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
|
||||
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
internal::max_coeff_visitor<Derived> maxVisitor;
|
||||
internal::max_coeff_visitor<Derived, NaNPropagation> maxVisitor;
|
||||
this->visit(maxVisitor);
|
||||
*index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row;
|
||||
return maxVisitor.res;
|
||||
|
||||
@@ -31,6 +31,52 @@ struct Packet2cf
|
||||
{
|
||||
EIGEN_STRONG_INLINE explicit Packet2cf() {}
|
||||
EIGEN_STRONG_INLINE explicit Packet2cf(const Packet4f& a) : v(a) {}
|
||||
|
||||
EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b)
|
||||
{
|
||||
Packet4f v1, v2;
|
||||
|
||||
// Permute and multiply the real parts of a and b
|
||||
v1 = vec_perm(a.v, a.v, p16uc_PSET32_WODD);
|
||||
// Get the imaginary parts of a
|
||||
v2 = vec_perm(a.v, a.v, p16uc_PSET32_WEVEN);
|
||||
// multiply a_re * b
|
||||
v1 = vec_madd(v1, b.v, p4f_ZERO);
|
||||
// multiply a_im * b and get the conjugate result
|
||||
v2 = vec_madd(v2, b.v, p4f_ZERO);
|
||||
v2 = reinterpret_cast<Packet4f>(pxor(v2, reinterpret_cast<Packet4f>(p4ui_CONJ_XOR)));
|
||||
// permute back to a proper order
|
||||
v2 = vec_perm(v2, v2, p16uc_COMPLEX32_REV);
|
||||
|
||||
return Packet2cf(padd<Packet4f>(v1, v2));
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE Packet2cf& operator*=(const Packet2cf& b) {
|
||||
v = pmul(Packet2cf(*this), b).v;
|
||||
return *this;
|
||||
}
|
||||
EIGEN_STRONG_INLINE Packet2cf operator*(const Packet2cf& b) const {
|
||||
return Packet2cf(*this) *= b;
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE Packet2cf& operator+=(const Packet2cf& b) {
|
||||
v = padd(v, b.v);
|
||||
return *this;
|
||||
}
|
||||
EIGEN_STRONG_INLINE Packet2cf operator+(const Packet2cf& b) const {
|
||||
return Packet2cf(*this) += b;
|
||||
}
|
||||
EIGEN_STRONG_INLINE Packet2cf& operator-=(const Packet2cf& b) {
|
||||
v = psub(v, b.v);
|
||||
return *this;
|
||||
}
|
||||
EIGEN_STRONG_INLINE Packet2cf operator-(const Packet2cf& b) const {
|
||||
return Packet2cf(*this) -= b;
|
||||
}
|
||||
EIGEN_STRONG_INLINE Packet2cf operator-(void) const {
|
||||
return Packet2cf(vec_neg(v));
|
||||
}
|
||||
|
||||
Packet4f v;
|
||||
};
|
||||
|
||||
@@ -81,6 +127,25 @@ template<> EIGEN_STRONG_INLINE Packet2cf ploaddup<Packet2cf>(const std::complex<
|
||||
template<> EIGEN_STRONG_INLINE void pstore <std::complex<float> >(std::complex<float> * to, const Packet2cf& from) { pstore((float*)to, from.v); }
|
||||
template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<float> >(std::complex<float> * to, const Packet2cf& from) { pstoreu((float*)to, from.v); }
|
||||
|
||||
EIGEN_STRONG_INLINE Packet2cf pload2(const std::complex<float>* from0, const std::complex<float>* from1)
|
||||
{
|
||||
Packet4f res0, res1;
|
||||
#ifdef __VSX__
|
||||
__asm__ ("lxsdx %x0,%y1" : "=wa" (res0) : "Z" (*from0));
|
||||
__asm__ ("lxsdx %x0,%y1" : "=wa" (res1) : "Z" (*from1));
|
||||
#ifdef _BIG_ENDIAN
|
||||
__asm__ ("xxpermdi %x0, %x1, %x2, 0" : "=wa" (res0) : "wa" (res0), "wa" (res1));
|
||||
#else
|
||||
__asm__ ("xxpermdi %x0, %x2, %x1, 0" : "=wa" (res0) : "wa" (res0), "wa" (res1));
|
||||
#endif
|
||||
#else
|
||||
*((std::complex<float> *)&res0[0]) = *from0;
|
||||
*((std::complex<float> *)&res1[0]) = *from1;
|
||||
res0 = vec_perm(res0, res1, p16uc_TRANSPOSE64_HI);
|
||||
#endif
|
||||
return Packet2cf(res0);
|
||||
}
|
||||
|
||||
template<> EIGEN_DEVICE_FUNC inline Packet2cf pgather<std::complex<float>, Packet2cf>(const std::complex<float>* from, Index stride)
|
||||
{
|
||||
EIGEN_ALIGN16 std::complex<float> af[2];
|
||||
@@ -101,25 +166,6 @@ template<> EIGEN_STRONG_INLINE Packet2cf psub<Packet2cf>(const Packet2cf& a, con
|
||||
template<> EIGEN_STRONG_INLINE Packet2cf pnegate(const Packet2cf& a) { return Packet2cf(pnegate(a.v)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet2cf pconj(const Packet2cf& a) { return Packet2cf(pxor<Packet4f>(a.v, reinterpret_cast<Packet4f>(p4ui_CONJ_XOR))); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2cf pmul<Packet2cf>(const Packet2cf& a, const Packet2cf& b)
|
||||
{
|
||||
Packet4f v1, v2;
|
||||
|
||||
// Permute and multiply the real parts of a and b
|
||||
v1 = vec_perm(a.v, a.v, p16uc_PSET32_WODD);
|
||||
// Get the imaginary parts of a
|
||||
v2 = vec_perm(a.v, a.v, p16uc_PSET32_WEVEN);
|
||||
// multiply a_re * b
|
||||
v1 = vec_madd(v1, b.v, p4f_ZERO);
|
||||
// multiply a_im * b and get the conjugate result
|
||||
v2 = vec_madd(v2, b.v, p4f_ZERO);
|
||||
v2 = reinterpret_cast<Packet4f>(pxor(v2, reinterpret_cast<Packet4f>(p4ui_CONJ_XOR)));
|
||||
// permute back to a proper order
|
||||
v2 = vec_perm(v2, v2, p16uc_COMPLEX32_REV);
|
||||
|
||||
return Packet2cf(padd<Packet4f>(v1, v2));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2cf pand <Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(pand<Packet4f>(a.v, b.v)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet2cf por <Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(por<Packet4f>(a.v, b.v)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet2cf pxor <Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(pxor<Packet4f>(a.v, b.v)); }
|
||||
@@ -239,6 +285,51 @@ struct Packet1cd
|
||||
{
|
||||
EIGEN_STRONG_INLINE Packet1cd() {}
|
||||
EIGEN_STRONG_INLINE explicit Packet1cd(const Packet2d& a) : v(a) {}
|
||||
|
||||
EIGEN_STRONG_INLINE Packet1cd pmul(const Packet1cd& a, const Packet1cd& b)
|
||||
{
|
||||
Packet2d a_re, a_im, v1, v2;
|
||||
|
||||
// Permute and multiply the real parts of a and b
|
||||
a_re = vec_perm(a.v, a.v, p16uc_PSET64_HI);
|
||||
// Get the imaginary parts of a
|
||||
a_im = vec_perm(a.v, a.v, p16uc_PSET64_LO);
|
||||
// multiply a_re * b
|
||||
v1 = vec_madd(a_re, b.v, p2d_ZERO);
|
||||
// multiply a_im * b and get the conjugate result
|
||||
v2 = vec_madd(a_im, b.v, p2d_ZERO);
|
||||
v2 = reinterpret_cast<Packet2d>(vec_sld(reinterpret_cast<Packet4ui>(v2), reinterpret_cast<Packet4ui>(v2), 8));
|
||||
v2 = pxor(v2, reinterpret_cast<Packet2d>(p2ul_CONJ_XOR1));
|
||||
|
||||
return Packet1cd(padd<Packet2d>(v1, v2));
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE Packet1cd& operator*=(const Packet1cd& b) {
|
||||
v = pmul(Packet1cd(*this), b).v;
|
||||
return *this;
|
||||
}
|
||||
EIGEN_STRONG_INLINE Packet1cd operator*(const Packet1cd& b) const {
|
||||
return Packet1cd(*this) *= b;
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE Packet1cd& operator+=(const Packet1cd& b) {
|
||||
v = padd(v, b.v);
|
||||
return *this;
|
||||
}
|
||||
EIGEN_STRONG_INLINE Packet1cd operator+(const Packet1cd& b) const {
|
||||
return Packet1cd(*this) += b;
|
||||
}
|
||||
EIGEN_STRONG_INLINE Packet1cd& operator-=(const Packet1cd& b) {
|
||||
v = psub(v, b.v);
|
||||
return *this;
|
||||
}
|
||||
EIGEN_STRONG_INLINE Packet1cd operator-(const Packet1cd& b) const {
|
||||
return Packet1cd(*this) -= b;
|
||||
}
|
||||
EIGEN_STRONG_INLINE Packet1cd operator-(void) const {
|
||||
return Packet1cd(vec_neg(v));
|
||||
}
|
||||
|
||||
Packet2d v;
|
||||
};
|
||||
|
||||
@@ -290,24 +381,6 @@ template<> EIGEN_STRONG_INLINE Packet1cd psub<Packet1cd>(const Packet1cd& a, con
|
||||
template<> EIGEN_STRONG_INLINE Packet1cd pnegate(const Packet1cd& a) { return Packet1cd(pnegate(Packet2d(a.v))); }
|
||||
template<> EIGEN_STRONG_INLINE Packet1cd pconj(const Packet1cd& a) { return Packet1cd(pxor(a.v, reinterpret_cast<Packet2d>(p2ul_CONJ_XOR2))); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet1cd pmul<Packet1cd>(const Packet1cd& a, const Packet1cd& b)
|
||||
{
|
||||
Packet2d a_re, a_im, v1, v2;
|
||||
|
||||
// Permute and multiply the real parts of a and b
|
||||
a_re = vec_perm(a.v, a.v, p16uc_PSET64_HI);
|
||||
// Get the imaginary parts of a
|
||||
a_im = vec_perm(a.v, a.v, p16uc_PSET64_LO);
|
||||
// multiply a_re * b
|
||||
v1 = vec_madd(a_re, b.v, p2d_ZERO);
|
||||
// multiply a_im * b and get the conjugate result
|
||||
v2 = vec_madd(a_im, b.v, p2d_ZERO);
|
||||
v2 = reinterpret_cast<Packet2d>(vec_sld(reinterpret_cast<Packet4ui>(v2), reinterpret_cast<Packet4ui>(v2), 8));
|
||||
v2 = pxor(v2, reinterpret_cast<Packet2d>(p2ul_CONJ_XOR1));
|
||||
|
||||
return Packet1cd(padd<Packet2d>(v1, v2));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet1cd pand <Packet1cd>(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(pand(a.v,b.v)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet1cd por <Packet1cd>(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(por(a.v,b.v)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet1cd pxor <Packet1cd>(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(pxor(a.v,b.v)); }
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,126 @@
|
||||
//#define EIGEN_POWER_USE_PREFETCH // Use prefetching in gemm routines
|
||||
#ifdef EIGEN_POWER_USE_PREFETCH
|
||||
#define EIGEN_POWER_PREFETCH(p) prefetch(p)
|
||||
#else
|
||||
#define EIGEN_POWER_PREFETCH(p)
|
||||
#endif
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename Scalar, typename Packet, typename DataMapper, typename Index, const Index accRows>
|
||||
EIGEN_STRONG_INLINE void gemm_extra_col(
|
||||
const DataMapper& res,
|
||||
const Scalar* lhs_base,
|
||||
const Scalar* rhs_base,
|
||||
Index depth,
|
||||
Index strideA,
|
||||
Index offsetA,
|
||||
Index row,
|
||||
Index col,
|
||||
Index remaining_rows,
|
||||
Index remaining_cols,
|
||||
const Packet& pAlpha);
|
||||
|
||||
template<typename Scalar, typename Packet, typename DataMapper, typename Index, const Index accRows, const Index accCols>
|
||||
EIGEN_STRONG_INLINE void gemm_extra_row(
|
||||
const DataMapper& res,
|
||||
const Scalar* lhs_base,
|
||||
const Scalar* rhs_base,
|
||||
Index depth,
|
||||
Index strideA,
|
||||
Index offsetA,
|
||||
Index row,
|
||||
Index col,
|
||||
Index rows,
|
||||
Index cols,
|
||||
Index remaining_rows,
|
||||
const Packet& pAlpha,
|
||||
const Packet& pMask);
|
||||
|
||||
template<typename Scalar, typename Packet, typename DataMapper, typename Index, const Index accCols>
|
||||
EIGEN_STRONG_INLINE void gemm_unrolled_col(
|
||||
const DataMapper& res,
|
||||
const Scalar* lhs_base,
|
||||
const Scalar* rhs_base,
|
||||
Index depth,
|
||||
Index strideA,
|
||||
Index offsetA,
|
||||
Index& row,
|
||||
Index rows,
|
||||
Index col,
|
||||
Index remaining_cols,
|
||||
const Packet& pAlpha);
|
||||
|
||||
template<typename Packet>
|
||||
EIGEN_STRONG_INLINE Packet bmask(const int remaining_rows);
|
||||
|
||||
template<typename Scalar, typename Packet, typename Packetc, typename DataMapper, typename Index, const Index accRows, const Index accCols, bool ConjugateLhs, bool ConjugateRhs, bool LhsIsReal, bool RhsIsReal>
|
||||
EIGEN_STRONG_INLINE void gemm_complex_extra_col(
|
||||
const DataMapper& res,
|
||||
const Scalar* lhs_base,
|
||||
const Scalar* rhs_base,
|
||||
Index depth,
|
||||
Index strideA,
|
||||
Index offsetA,
|
||||
Index strideB,
|
||||
Index row,
|
||||
Index col,
|
||||
Index remaining_rows,
|
||||
Index remaining_cols,
|
||||
const Packet& pAlphaReal,
|
||||
const Packet& pAlphaImag);
|
||||
|
||||
template<typename Scalar, typename Packet, typename Packetc, typename DataMapper, typename Index, const Index accRows, const Index accCols, bool ConjugateLhs, bool ConjugateRhs, bool LhsIsReal, bool RhsIsReal>
|
||||
EIGEN_STRONG_INLINE void gemm_complex_extra_row(
|
||||
const DataMapper& res,
|
||||
const Scalar* lhs_base,
|
||||
const Scalar* rhs_base,
|
||||
Index depth,
|
||||
Index strideA,
|
||||
Index offsetA,
|
||||
Index strideB,
|
||||
Index row,
|
||||
Index col,
|
||||
Index rows,
|
||||
Index cols,
|
||||
Index remaining_rows,
|
||||
const Packet& pAlphaReal,
|
||||
const Packet& pAlphaImag,
|
||||
const Packet& pMask);
|
||||
|
||||
template<typename Scalar, typename Packet, typename Packetc, typename DataMapper, typename Index, const Index accCols, bool ConjugateLhs, bool ConjugateRhs, bool LhsIsReal, bool RhsIsReal>
|
||||
EIGEN_STRONG_INLINE void gemm_complex_unrolled_col(
|
||||
const DataMapper& res,
|
||||
const Scalar* lhs_base,
|
||||
const Scalar* rhs_base,
|
||||
Index depth,
|
||||
Index strideA,
|
||||
Index offsetA,
|
||||
Index strideB,
|
||||
Index& row,
|
||||
Index rows,
|
||||
Index col,
|
||||
Index remaining_cols,
|
||||
const Packet& pAlphaReal,
|
||||
const Packet& pAlphaImag);
|
||||
|
||||
template<typename Scalar, typename Packet>
|
||||
EIGEN_STRONG_INLINE Packet ploadLhs(const Scalar* lhs);
|
||||
|
||||
template<typename DataMapper, typename Packet, typename Index, const Index accCols, int N, int StorageOrder>
|
||||
EIGEN_STRONG_INLINE void bload(PacketBlock<Packet,4>& acc, const DataMapper& res, Index row, Index col);
|
||||
|
||||
template<typename DataMapper, typename Packet, typename Index, const Index accCols, int N, int StorageOrder>
|
||||
EIGEN_STRONG_INLINE void bload(PacketBlock<Packet,8>& acc, const DataMapper& res, Index row, Index col);
|
||||
|
||||
template<typename Packet>
|
||||
EIGEN_STRONG_INLINE void bscale(PacketBlock<Packet,4>& acc, PacketBlock<Packet,4>& accZ, const Packet& pAlpha);
|
||||
|
||||
template<typename Packet, int N>
|
||||
EIGEN_STRONG_INLINE void bscalec(PacketBlock<Packet,N>& aReal, PacketBlock<Packet,N>& aImag, const Packet& bReal, const Packet& bImag, PacketBlock<Packet,N>& cReal, PacketBlock<Packet,N>& cImag);
|
||||
|
||||
const static Packet16uc p16uc_SETCOMPLEX32_FIRST = { 0, 1, 2, 3,
|
||||
16, 17, 18, 19,
|
||||
4, 5, 6, 7,
|
||||
@@ -22,7 +141,7 @@ const static Packet16uc p16uc_SETCOMPLEX64_SECOND = { 8, 9, 10, 11, 12, 13, 14
|
||||
|
||||
// Grab two decouples real/imaginary PacketBlocks and return two coupled (real/imaginary pairs) PacketBlocks.
|
||||
template<typename Packet, typename Packetc>
|
||||
EIGEN_STRONG_INLINE void bcouple(PacketBlock<Packet,4>& taccReal, PacketBlock<Packet,4>& taccImag, PacketBlock<Packetc,8>& tRes, PacketBlock<Packetc, 4>& acc1, PacketBlock<Packetc, 4>& acc2)
|
||||
EIGEN_STRONG_INLINE void bcouple_common(PacketBlock<Packet,4>& taccReal, PacketBlock<Packet,4>& taccImag, PacketBlock<Packetc, 4>& acc1, PacketBlock<Packetc, 4>& acc2)
|
||||
{
|
||||
acc1.packet[0].v = vec_perm(taccReal.packet[0], taccImag.packet[0], p16uc_SETCOMPLEX32_FIRST);
|
||||
acc1.packet[1].v = vec_perm(taccReal.packet[1], taccImag.packet[1], p16uc_SETCOMPLEX32_FIRST);
|
||||
@@ -33,6 +152,12 @@ EIGEN_STRONG_INLINE void bcouple(PacketBlock<Packet,4>& taccReal, PacketBlock<Pa
|
||||
acc2.packet[1].v = vec_perm(taccReal.packet[1], taccImag.packet[1], p16uc_SETCOMPLEX32_SECOND);
|
||||
acc2.packet[2].v = vec_perm(taccReal.packet[2], taccImag.packet[2], p16uc_SETCOMPLEX32_SECOND);
|
||||
acc2.packet[3].v = vec_perm(taccReal.packet[3], taccImag.packet[3], p16uc_SETCOMPLEX32_SECOND);
|
||||
}
|
||||
|
||||
template<typename Packet, typename Packetc>
|
||||
EIGEN_STRONG_INLINE void bcouple(PacketBlock<Packet,4>& taccReal, PacketBlock<Packet,4>& taccImag, PacketBlock<Packetc,8>& tRes, PacketBlock<Packetc, 4>& acc1, PacketBlock<Packetc, 4>& acc2)
|
||||
{
|
||||
bcouple_common<Packet, Packetc>(taccReal, taccImag, acc1, acc2);
|
||||
|
||||
acc1.packet[0] = padd<Packetc>(tRes.packet[0], acc1.packet[0]);
|
||||
acc1.packet[1] = padd<Packetc>(tRes.packet[1], acc1.packet[1]);
|
||||
@@ -45,8 +170,26 @@ EIGEN_STRONG_INLINE void bcouple(PacketBlock<Packet,4>& taccReal, PacketBlock<Pa
|
||||
acc2.packet[3] = padd<Packetc>(tRes.packet[7], acc2.packet[3]);
|
||||
}
|
||||
|
||||
template<typename Packet, typename Packetc>
|
||||
EIGEN_STRONG_INLINE void bcouple_common(PacketBlock<Packet,1>& taccReal, PacketBlock<Packet,1>& taccImag, PacketBlock<Packetc, 1>& acc1, PacketBlock<Packetc, 1>& acc2)
|
||||
{
|
||||
acc1.packet[0].v = vec_perm(taccReal.packet[0], taccImag.packet[0], p16uc_SETCOMPLEX32_FIRST);
|
||||
|
||||
acc2.packet[0].v = vec_perm(taccReal.packet[0], taccImag.packet[0], p16uc_SETCOMPLEX32_SECOND);
|
||||
}
|
||||
|
||||
template<typename Packet, typename Packetc>
|
||||
EIGEN_STRONG_INLINE void bcouple(PacketBlock<Packet,1>& taccReal, PacketBlock<Packet,1>& taccImag, PacketBlock<Packetc,2>& tRes, PacketBlock<Packetc, 1>& acc1, PacketBlock<Packetc, 1>& acc2)
|
||||
{
|
||||
bcouple_common<Packet, Packetc>(taccReal, taccImag, acc1, acc2);
|
||||
|
||||
acc1.packet[0] = padd<Packetc>(tRes.packet[0], acc1.packet[0]);
|
||||
|
||||
acc2.packet[0] = padd<Packetc>(tRes.packet[1], acc2.packet[0]);
|
||||
}
|
||||
|
||||
template<>
|
||||
EIGEN_STRONG_INLINE void bcouple<Packet2d, Packet1cd>(PacketBlock<Packet2d,4>& taccReal, PacketBlock<Packet2d,4>& taccImag, PacketBlock<Packet1cd,8>& tRes, PacketBlock<Packet1cd, 4>& acc1, PacketBlock<Packet1cd, 4>& acc2)
|
||||
EIGEN_STRONG_INLINE void bcouple_common<Packet2d, Packet1cd>(PacketBlock<Packet2d,4>& taccReal, PacketBlock<Packet2d,4>& taccImag, PacketBlock<Packet1cd, 4>& acc1, PacketBlock<Packet1cd, 4>& acc2)
|
||||
{
|
||||
acc1.packet[0].v = vec_perm(taccReal.packet[0], taccImag.packet[0], p16uc_SETCOMPLEX64_FIRST);
|
||||
acc1.packet[1].v = vec_perm(taccReal.packet[1], taccImag.packet[1], p16uc_SETCOMPLEX64_FIRST);
|
||||
@@ -57,23 +200,21 @@ EIGEN_STRONG_INLINE void bcouple<Packet2d, Packet1cd>(PacketBlock<Packet2d,4>& t
|
||||
acc2.packet[1].v = vec_perm(taccReal.packet[1], taccImag.packet[1], p16uc_SETCOMPLEX64_SECOND);
|
||||
acc2.packet[2].v = vec_perm(taccReal.packet[2], taccImag.packet[2], p16uc_SETCOMPLEX64_SECOND);
|
||||
acc2.packet[3].v = vec_perm(taccReal.packet[3], taccImag.packet[3], p16uc_SETCOMPLEX64_SECOND);
|
||||
}
|
||||
|
||||
acc1.packet[0] = padd<Packet1cd>(tRes.packet[0], acc1.packet[0]);
|
||||
acc1.packet[1] = padd<Packet1cd>(tRes.packet[1], acc1.packet[1]);
|
||||
acc1.packet[2] = padd<Packet1cd>(tRes.packet[2], acc1.packet[2]);
|
||||
acc1.packet[3] = padd<Packet1cd>(tRes.packet[3], acc1.packet[3]);
|
||||
template<>
|
||||
EIGEN_STRONG_INLINE void bcouple_common<Packet2d, Packet1cd>(PacketBlock<Packet2d,1>& taccReal, PacketBlock<Packet2d,1>& taccImag, PacketBlock<Packet1cd, 1>& acc1, PacketBlock<Packet1cd, 1>& acc2)
|
||||
{
|
||||
acc1.packet[0].v = vec_perm(taccReal.packet[0], taccImag.packet[0], p16uc_SETCOMPLEX64_FIRST);
|
||||
|
||||
acc2.packet[0] = padd<Packet1cd>(tRes.packet[4], acc2.packet[0]);
|
||||
acc2.packet[1] = padd<Packet1cd>(tRes.packet[5], acc2.packet[1]);
|
||||
acc2.packet[2] = padd<Packet1cd>(tRes.packet[6], acc2.packet[2]);
|
||||
acc2.packet[3] = padd<Packet1cd>(tRes.packet[7], acc2.packet[3]);
|
||||
acc2.packet[0].v = vec_perm(taccReal.packet[0], taccImag.packet[0], p16uc_SETCOMPLEX64_SECOND);
|
||||
}
|
||||
|
||||
// This is necessary because ploadRhs for double returns a pair of vectors when MMA is enabled.
|
||||
template<typename Scalar, typename Packet>
|
||||
EIGEN_STRONG_INLINE Packet ploadRhs(const Scalar *rhs)
|
||||
EIGEN_STRONG_INLINE Packet ploadRhs(const Scalar* rhs)
|
||||
{
|
||||
return *((Packet *)rhs);
|
||||
return *((Packet *)rhs);
|
||||
}
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -188,6 +188,7 @@ struct packet_traits<float> : default_packet_traits {
|
||||
HasRound = 1,
|
||||
HasFloor = 1,
|
||||
HasCeil = 1,
|
||||
HasRint = 1,
|
||||
HasNegate = 1,
|
||||
HasBlend = 1
|
||||
};
|
||||
@@ -229,6 +230,7 @@ struct packet_traits<bfloat16> : default_packet_traits {
|
||||
HasRound = 1,
|
||||
HasFloor = 1,
|
||||
HasCeil = 1,
|
||||
HasRint = 1,
|
||||
HasNegate = 1,
|
||||
HasBlend = 1
|
||||
};
|
||||
@@ -911,18 +913,35 @@ template<> EIGEN_STRONG_INLINE Packet4f pselect(const Packet4f& mask, const Pack
|
||||
return vec_sel(b, a, reinterpret_cast<Packet4ui>(mask));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pround<Packet4f>(const Packet4f& a) {
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pround<Packet4f>(const Packet4f& a)
|
||||
{
|
||||
Packet4f t = vec_add(reinterpret_cast<Packet4f>(vec_or(vec_and(reinterpret_cast<Packet4ui>(a), p4ui_SIGN), p4ui_PREV0DOT5)), a);
|
||||
Packet4f res;
|
||||
|
||||
#ifdef __VSX__
|
||||
__asm__("xvrspiz %x0, %x1\n\t"
|
||||
: "=&wa" (res)
|
||||
: "wa" (t));
|
||||
#else
|
||||
__asm__("vrfiz %0, %1\n\t"
|
||||
: "=v" (res)
|
||||
: "v" (t));
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pceil<Packet4f>(const Packet4f& a) { return vec_ceil(a); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pfloor<Packet4f>(const Packet4f& a) { return vec_floor(a); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4f print<Packet4f>(const Packet4f& a)
|
||||
{
|
||||
Packet4f res;
|
||||
|
||||
__asm__("xvrspic %x0, %x1\n\t"
|
||||
: "=&wa" (res)
|
||||
: "wa" (a));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
template<typename Packet> EIGEN_STRONG_INLINE Packet ploadu_common(const __UNPACK_TYPE__(Packet)* from)
|
||||
{
|
||||
@@ -1366,6 +1385,9 @@ template<> EIGEN_STRONG_INLINE Packet8bf pceil<Packet8bf> (const Packet8bf& a){
|
||||
template<> EIGEN_STRONG_INLINE Packet8bf pround<Packet8bf> (const Packet8bf& a){
|
||||
BF16_TO_F32_UNARY_OP_WRAPPER(pround<Packet4f>, a);
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE Packet8bf print<Packet8bf> (const Packet8bf& a){
|
||||
BF16_TO_F32_UNARY_OP_WRAPPER(print<Packet4f>, a);
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE Packet8bf pmadd(const Packet8bf& a, const Packet8bf& b, const Packet8bf& c) {
|
||||
Packet4f a_even = Bf16ToF32Even(a);
|
||||
Packet4f a_odd = Bf16ToF32Odd(a);
|
||||
@@ -2234,6 +2256,8 @@ typedef __vector __bool long Packet2bl;
|
||||
|
||||
static Packet2l p2l_ONE = { 1, 1 };
|
||||
static Packet2l p2l_ZERO = reinterpret_cast<Packet2l>(p4i_ZERO);
|
||||
static Packet2ul p2ul_SIGN = { 0x8000000000000000ull, 0x8000000000000000ull };
|
||||
static Packet2ul p2ul_PREV0DOT5 = { 0x3FDFFFFFFFFFFFFFull, 0x3FDFFFFFFFFFFFFFull };
|
||||
static Packet2d p2d_ONE = { 1.0, 1.0 };
|
||||
static Packet2d p2d_ZERO = reinterpret_cast<Packet2d>(p4f_ZERO);
|
||||
static Packet2d p2d_MZERO = { -0.0, -0.0 };
|
||||
@@ -2244,16 +2268,9 @@ static Packet2d p2d_COUNTDOWN = reinterpret_cast<Packet2d>(vec_sld(reinterpret_c
|
||||
static Packet2d p2d_COUNTDOWN = reinterpret_cast<Packet2d>(vec_sld(reinterpret_cast<Packet4f>(p2d_ONE), reinterpret_cast<Packet4f>(p2d_ZERO), 8));
|
||||
#endif
|
||||
|
||||
template<int index> Packet2d vec_splat_dbl(Packet2d& a);
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2d vec_splat_dbl<0>(Packet2d& a)
|
||||
template<int index> Packet2d vec_splat_dbl(Packet2d& a)
|
||||
{
|
||||
return reinterpret_cast<Packet2d>(vec_perm(a, a, p16uc_PSET64_HI));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2d vec_splat_dbl<1>(Packet2d& a)
|
||||
{
|
||||
return reinterpret_cast<Packet2d>(vec_perm(a, a, p16uc_PSET64_LO));
|
||||
return vec_splat(a, index);
|
||||
}
|
||||
|
||||
template<> struct packet_traits<double> : default_packet_traits
|
||||
@@ -2282,6 +2299,7 @@ template<> struct packet_traits<double> : default_packet_traits
|
||||
HasRound = 1,
|
||||
HasFloor = 1,
|
||||
HasCeil = 1,
|
||||
HasRint = 1,
|
||||
HasNegate = 1,
|
||||
HasBlend = 1
|
||||
};
|
||||
@@ -2408,9 +2426,29 @@ template<> EIGEN_STRONG_INLINE Packet2d pxor<Packet2d>(const Packet2d& a, const
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pandnot<Packet2d>(const Packet2d& a, const Packet2d& b) { return vec_and(a, vec_nor(b, b)); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pround<Packet2d>(const Packet2d& a) { return vec_round(a); }
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pround<Packet2d>(const Packet2d& a)
|
||||
{
|
||||
Packet2d t = vec_add(reinterpret_cast<Packet2d>(vec_or(vec_and(reinterpret_cast<Packet2ul>(a), p2ul_SIGN), p2ul_PREV0DOT5)), a);
|
||||
Packet2d res;
|
||||
|
||||
__asm__("xvrdpiz %x0, %x1\n\t"
|
||||
: "=&wa" (res)
|
||||
: "wa" (t));
|
||||
|
||||
return res;
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pceil<Packet2d>(const Packet2d& a) { return vec_ceil(a); }
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pfloor<Packet2d>(const Packet2d& a) { return vec_floor(a); }
|
||||
template<> EIGEN_STRONG_INLINE Packet2d print<Packet2d>(const Packet2d& a)
|
||||
{
|
||||
Packet2d res;
|
||||
|
||||
__asm__("xvrdpic %x0, %x1\n\t"
|
||||
: "=&wa" (res)
|
||||
: "wa" (a));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2d ploadu<Packet2d>(const double* from)
|
||||
{
|
||||
|
||||
@@ -12,9 +12,6 @@
|
||||
#define EIGEN_COMPLEX_CUDA_H
|
||||
|
||||
// clang-format off
|
||||
|
||||
#if defined(EIGEN_CUDACC) && defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
|
||||
// Many std::complex methods such as operator+, operator-, operator* and
|
||||
// operator/ are not constexpr. Due to this, GCC and older versions of clang do
|
||||
// not treat them as device functions and thus Eigen functors making use of
|
||||
@@ -22,6 +19,17 @@
|
||||
// operators and functors for complex types when building for CUDA to enable
|
||||
// their use on-device.
|
||||
|
||||
#if defined(EIGEN_CUDACC) && defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
|
||||
// ICC already specializes std::complex<float> and std::complex<double>
|
||||
// operators, preventing us from making them device functions here.
|
||||
// This will lead to silent runtime errors if the operators are used on device.
|
||||
//
|
||||
// To allow std::complex operator use on device, define _OVERRIDE_COMPLEX_SPECIALIZATION_
|
||||
// prior to first inclusion of <complex>. This prevents ICC from adding
|
||||
// its own specializations, so our custom ones below can be used instead.
|
||||
#if !(defined(EIGEN_COMP_ICC) && defined(_USE_COMPLEX_SPECIALIZATION_))
|
||||
|
||||
// Import Eigen's internal operator specializations.
|
||||
#define EIGEN_USING_STD_COMPLEX_OPERATORS \
|
||||
using Eigen::complex_operator_detail::operator+; \
|
||||
@@ -244,6 +252,8 @@ EIGEN_USING_STD_COMPLEX_OPERATORS
|
||||
} // namespace internal
|
||||
} // namespace Eigen
|
||||
|
||||
#endif
|
||||
#endif // !(EIGEN_COMP_ICC && _USE_COMPLEX_SPECIALIZATION_)
|
||||
|
||||
#endif // EIGEN_CUDACC && EIGEN_GPU_COMPILE_PHASE
|
||||
|
||||
#endif // EIGEN_COMPLEX_CUDA_H
|
||||
|
||||
@@ -67,7 +67,7 @@ struct bfloat16 : public bfloat16_impl::bfloat16_base {
|
||||
: bfloat16_impl::bfloat16_base(bfloat16_impl::raw_uint16_to_bfloat16(b ? 0x3f80 : 0)) {}
|
||||
|
||||
template<class T>
|
||||
explicit EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bfloat16(const T& val)
|
||||
explicit EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bfloat16(T val)
|
||||
: bfloat16_impl::bfloat16_base(bfloat16_impl::float_to_bfloat16_rtne<internal::is_integral<T>::value>(static_cast<float>(val))) {}
|
||||
|
||||
explicit EIGEN_DEVICE_FUNC bfloat16(float f)
|
||||
@@ -562,11 +562,14 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 atanh(const bfloat16& a) {
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 floor(const bfloat16& a) {
|
||||
return bfloat16(::floorf(float(a)));
|
||||
}
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 ceil(const bfloat16& a) {
|
||||
return bfloat16(::ceilf(float(a)));
|
||||
}
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 rint(const bfloat16& a) {
|
||||
return bfloat16(::rintf(float(a)));
|
||||
}
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 ceil(const bfloat16& a) {
|
||||
return bfloat16(::ceilf(float(a)));
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 round(const bfloat16& a) {
|
||||
return bfloat16(::roundf(float(a)));
|
||||
}
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 fmod(const bfloat16& a, const bfloat16& b) {
|
||||
return bfloat16(::fmodf(float(a), float(b)));
|
||||
@@ -655,20 +658,6 @@ template<> struct NumTraits<Eigen::bfloat16>
|
||||
|
||||
} // namespace Eigen
|
||||
|
||||
namespace std {
|
||||
|
||||
#if __cplusplus > 199711L
|
||||
template <>
|
||||
struct hash<Eigen::bfloat16> {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::size_t operator()(const Eigen::bfloat16& a) const {
|
||||
return hash<float>()(static_cast<float>(a));
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace std
|
||||
|
||||
|
||||
namespace Eigen {
|
||||
namespace numext {
|
||||
|
||||
@@ -703,4 +692,16 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC uint16_t bit_cast<uint16_t, Eigen::bfloat1
|
||||
} // namespace numext
|
||||
} // namespace Eigen
|
||||
|
||||
#if EIGEN_HAS_STD_HASH
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<Eigen::bfloat16> {
|
||||
EIGEN_STRONG_INLINE std::size_t operator()(const Eigen::bfloat16& a) const {
|
||||
return static_cast<std::size_t>(Eigen::numext::bit_cast<Eigen::numext::uint16_t>(a));
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
#endif
|
||||
|
||||
|
||||
#endif // EIGEN_BFLOAT16_H
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
@@ -136,7 +135,7 @@ Packet pldexp_generic(const Packet& a, const Packet& exponent) {
|
||||
// Explicitly multiplies
|
||||
// a * (2^e)
|
||||
// clamping e to the range
|
||||
// [numeric_limits<Scalar>::min_exponent-2, numeric_limits<Scalar>::max_exponent]
|
||||
// [NumTraits<Scalar>::min_exponent()-2, NumTraits<Scalar>::max_exponent()]
|
||||
//
|
||||
// This is approx 7x faster than pldexp_impl, but will prematurely over/underflow
|
||||
// if 2^e doesn't fit into a normal floating-point Scalar.
|
||||
@@ -468,16 +467,10 @@ Packet pexp_float(const Packet _x)
|
||||
// Get r = x - m*ln(2). If no FMA instructions are available, m*ln(2) is
|
||||
// subtracted out in two parts, m*C1+m*C2 = m*ln(2), to avoid accumulating
|
||||
// truncation errors.
|
||||
Packet r;
|
||||
#ifdef EIGEN_HAS_SINGLE_INSTRUCTION_MADD
|
||||
const Packet cst_nln2 = pset1<Packet>(-0.6931471805599453f);
|
||||
r = pmadd(m, cst_nln2, x);
|
||||
#else
|
||||
const Packet cst_cephes_exp_C1 = pset1<Packet>(0.693359375f);
|
||||
const Packet cst_cephes_exp_C2 = pset1<Packet>(-2.12194440e-4f);
|
||||
r = psub(x, pmul(m, cst_cephes_exp_C1));
|
||||
r = psub(r, pmul(m, cst_cephes_exp_C2));
|
||||
#endif
|
||||
const Packet cst_cephes_exp_C1 = pset1<Packet>(-0.693359375f);
|
||||
const Packet cst_cephes_exp_C2 = pset1<Packet>(2.12194440e-4f);
|
||||
Packet r = pmadd(m, cst_cephes_exp_C1, x);
|
||||
r = pmadd(m, cst_cephes_exp_C2, r);
|
||||
|
||||
Packet r2 = pmul(r, r);
|
||||
Packet r3 = pmul(r2, r);
|
||||
@@ -491,7 +484,7 @@ Packet pexp_float(const Packet _x)
|
||||
y1 = pmadd(y1, r, cst_cephes_exp_p5);
|
||||
y = pmadd(y, r3, y1);
|
||||
y = pmadd(y, r2, y2);
|
||||
|
||||
|
||||
// Return 2^m * exp(r).
|
||||
// TODO: replace pldexp with faster implementation since y in [-1, 1).
|
||||
return pmax(pldexp(y,m), _x);
|
||||
@@ -637,14 +630,6 @@ __attribute__((optimize("-fno-unsafe-math-optimizations")))
|
||||
#endif
|
||||
Packet psincos_float(const Packet& _x)
|
||||
{
|
||||
// Workaround -ffast-math aggressive optimizations
|
||||
// See bug 1674
|
||||
#if EIGEN_COMP_CLANG && defined(EIGEN_VECTORIZE_SSE)
|
||||
#define EIGEN_SINCOS_DONT_OPT(X) __asm__ ("" : "+x" (X));
|
||||
#else
|
||||
#define EIGEN_SINCOS_DONT_OPT(X)
|
||||
#endif
|
||||
|
||||
typedef typename unpacket_traits<Packet>::integer_packet PacketI;
|
||||
|
||||
const Packet cst_2oPI = pset1<Packet>(0.636619746685028076171875f); // 2/PI
|
||||
@@ -659,7 +644,7 @@ Packet psincos_float(const Packet& _x)
|
||||
|
||||
// Rounding trick:
|
||||
Packet y_round = padd(y, cst_rounding_magic);
|
||||
EIGEN_SINCOS_DONT_OPT(y_round)
|
||||
EIGEN_OPTIMIZATION_BARRIER(y_round)
|
||||
PacketI y_int = preinterpret<PacketI>(y_round); // last 23 digits represent integer (if abs(x)<2^24)
|
||||
y = psub(y_round, cst_rounding_magic); // nearest integer to x*4/pi
|
||||
|
||||
@@ -681,9 +666,9 @@ Packet psincos_float(const Packet& _x)
|
||||
// and 2 ULP up to:
|
||||
const float huge_th = ComputeSine ? 25966.f : 18838.f;
|
||||
x = pmadd(y, pset1<Packet>(-1.5703125), x); // = 0xbfc90000
|
||||
EIGEN_SINCOS_DONT_OPT(x)
|
||||
EIGEN_OPTIMIZATION_BARRIER(x)
|
||||
x = pmadd(y, pset1<Packet>(-0.000483989715576171875), x); // = 0xb9fdc000
|
||||
EIGEN_SINCOS_DONT_OPT(x)
|
||||
EIGEN_OPTIMIZATION_BARRIER(x)
|
||||
x = pmadd(y, pset1<Packet>(1.62865035235881805419921875e-07), x); // = 0x342ee000
|
||||
x = pmadd(y, pset1<Packet>(5.5644315544167710640977020375430583953857421875e-11), x); // = 0x2e74b9ee
|
||||
|
||||
@@ -760,8 +745,6 @@ Packet psincos_float(const Packet& _x)
|
||||
|
||||
// Update the sign and filter huge inputs
|
||||
return pxor(y, sign_bit);
|
||||
|
||||
#undef EIGEN_SINCOS_DONT_OPT
|
||||
}
|
||||
|
||||
template<typename Packet>
|
||||
@@ -1010,6 +993,20 @@ EIGEN_STRONG_INLINE
|
||||
fast_twosum(r_hi, s, s_hi, s_lo);
|
||||
}
|
||||
|
||||
// This is a version of twosum for adding a floating point number x to
|
||||
// double word number {y_hi, y_lo} number, with the assumption
|
||||
// that |x| >= |y_hi|.
|
||||
template<typename Packet>
|
||||
EIGEN_STRONG_INLINE
|
||||
void fast_twosum(const Packet& x,
|
||||
const Packet& y_hi, const Packet& y_lo,
|
||||
Packet& s_hi, Packet& s_lo) {
|
||||
Packet r_hi, r_lo;
|
||||
fast_twosum(x, y_hi, r_hi, r_lo);
|
||||
const Packet s = padd(y_lo, r_lo);
|
||||
fast_twosum(r_hi, s, s_hi, s_lo);
|
||||
}
|
||||
|
||||
// This function implements the multiplication of a double word
|
||||
// number represented by {x_hi, x_lo} by a floating point number y.
|
||||
// It returns the result as a pair {p_hi, p_lo} such that
|
||||
@@ -1031,6 +1028,50 @@ void twoprod(const Packet& x_hi, const Packet& x_lo, const Packet& y,
|
||||
fast_twosum(t_hi, t_lo2, p_hi, p_lo);
|
||||
}
|
||||
|
||||
// This function implements the multiplication of two double word
|
||||
// numbers represented by {x_hi, x_lo} and {y_hi, y_lo}.
|
||||
// It returns the result as a pair {p_hi, p_lo} such that
|
||||
// (x_hi + x_lo) * (y_hi + y_lo) = p_hi + p_lo holds with a relative error
|
||||
// of less than 2*2^{-2p}, where p is the number of significand bit
|
||||
// in the floating point type.
|
||||
template<typename Packet>
|
||||
EIGEN_STRONG_INLINE
|
||||
void twoprod(const Packet& x_hi, const Packet& x_lo,
|
||||
const Packet& y_hi, const Packet& y_lo,
|
||||
Packet& p_hi, Packet& p_lo) {
|
||||
Packet p_hi_hi, p_hi_lo;
|
||||
twoprod(x_hi, x_lo, y_hi, p_hi_hi, p_hi_lo);
|
||||
Packet p_lo_hi, p_lo_lo;
|
||||
twoprod(x_hi, x_lo, y_lo, p_lo_hi, p_lo_lo);
|
||||
fast_twosum(p_hi_hi, p_hi_lo, p_lo_hi, p_lo_lo, p_hi, p_lo);
|
||||
}
|
||||
|
||||
// This function computes the reciprocal of a floating point number
|
||||
// with extra precision and returns the result as a double word.
|
||||
template <typename Packet>
|
||||
void doubleword_reciprocal(const Packet& x, Packet& recip_hi, Packet& recip_lo) {
|
||||
typedef typename unpacket_traits<Packet>::type Scalar;
|
||||
// 1. Approximate the reciprocal as the reciprocal of the high order element.
|
||||
Packet approx_recip = prsqrt(x);
|
||||
approx_recip = pmul(approx_recip, approx_recip);
|
||||
|
||||
// 2. Run one step of Newton-Raphson iteration in double word arithmetic
|
||||
// to get the bottom half. The NR iteration for reciprocal of 'a' is
|
||||
// x_{i+1} = x_i * (2 - a * x_i)
|
||||
|
||||
// -a*x_i
|
||||
Packet t1_hi, t1_lo;
|
||||
twoprod(pnegate(x), approx_recip, t1_hi, t1_lo);
|
||||
// 2 - a*x_i
|
||||
Packet t2_hi, t2_lo;
|
||||
fast_twosum(pset1<Packet>(Scalar(2)), t1_hi, t2_hi, t2_lo);
|
||||
Packet t3_hi, t3_lo;
|
||||
fast_twosum(t2_hi, padd(t2_lo, t1_lo), t3_hi, t3_lo);
|
||||
// x_i * (2 - a * x_i)
|
||||
twoprod(t3_hi, t3_lo, approx_recip, recip_hi, recip_lo);
|
||||
}
|
||||
|
||||
|
||||
// This function computes log2(x) and returns the result as a double word.
|
||||
template <typename Scalar>
|
||||
struct accurate_log2 {
|
||||
@@ -1122,6 +1163,101 @@ struct accurate_log2<float> {
|
||||
}
|
||||
};
|
||||
|
||||
// This specialization uses a more accurate algorithm to compute log2(x) for
|
||||
// floats in [1/sqrt(2);sqrt(2)] with a relative accuracy of ~1.27e-18.
|
||||
// This additional accuracy is needed to counter the error-magnification
|
||||
// inherent in multiplying by a potentially large exponent in pow(x,y).
|
||||
// The minimax polynomial used was calculated using the Sollya tool.
|
||||
// See sollya.org.
|
||||
|
||||
template <>
|
||||
struct accurate_log2<double> {
|
||||
template <typename Packet>
|
||||
EIGEN_STRONG_INLINE
|
||||
void operator()(const Packet& x, Packet& log2_x_hi, Packet& log2_x_lo) {
|
||||
// We use a transformation of variables:
|
||||
// r = c * (x-1) / (x+1),
|
||||
// such that
|
||||
// log2(x) = log2((1 + r/c) / (1 - r/c)) = f(r).
|
||||
// The function f(r) can be approximated well using an odd polynomial
|
||||
// of the form
|
||||
// P(r) = ((Q(r^2) * r^2 + C) * r^2 + 1) * r,
|
||||
// For the implementation of log2<double> here, Q is of degree 6 with
|
||||
// coefficient represented in working precision (double), while C is a
|
||||
// constant represented in extra precision as a double word to achieve
|
||||
// full accuracy.
|
||||
//
|
||||
// The polynomial coefficients were computed by the Sollya script:
|
||||
//
|
||||
// c = 2 / log(2);
|
||||
// trans = c * (x-1)/(x+1);
|
||||
// itrans = (1+x/c)/(1-x/c);
|
||||
// interval=[trans(sqrt(0.5)); trans(sqrt(2))];
|
||||
// print(interval);
|
||||
// f = log2(itrans(x));
|
||||
// p=fpminimax(f,[|1,3,5,7,9,11,13,15,17|],[|1,DD,double...|],interval,relative,floating);
|
||||
const Packet q12 = pset1<Packet>(2.87074255468000586e-9);
|
||||
const Packet q10 = pset1<Packet>(2.38957980901884082e-8);
|
||||
const Packet q8 = pset1<Packet>(2.31032094540014656e-7);
|
||||
const Packet q6 = pset1<Packet>(2.27279857398537278e-6);
|
||||
const Packet q4 = pset1<Packet>(2.31271023278625638e-5);
|
||||
const Packet q2 = pset1<Packet>(2.47556738444535513e-4);
|
||||
const Packet q0 = pset1<Packet>(2.88543873228900172e-3);
|
||||
const Packet C_hi = pset1<Packet>(0.0400377511598501157);
|
||||
const Packet C_lo = pset1<Packet>(-4.77726582251425391e-19);
|
||||
const Packet one = pset1<Packet>(1.0);
|
||||
|
||||
const Packet cst_2_log2e_hi = pset1<Packet>(2.88539008177792677);
|
||||
const Packet cst_2_log2e_lo = pset1<Packet>(4.07660016854549667e-17);
|
||||
// c * (x - 1)
|
||||
Packet num_hi, num_lo;
|
||||
twoprod(cst_2_log2e_hi, cst_2_log2e_lo, psub(x, one), num_hi, num_lo);
|
||||
// TODO(rmlarsen): Investigate if using the division algorithm by
|
||||
// Muller et al. is faster/more accurate.
|
||||
// 1 / (x + 1)
|
||||
Packet denom_hi, denom_lo;
|
||||
doubleword_reciprocal(padd(x, one), denom_hi, denom_lo);
|
||||
// r = c * (x-1) / (x+1),
|
||||
Packet r_hi, r_lo;
|
||||
twoprod(num_hi, num_lo, denom_hi, denom_lo, r_hi, r_lo);
|
||||
// r2 = r * r
|
||||
Packet r2_hi, r2_lo;
|
||||
twoprod(r_hi, r_lo, r_hi, r_lo, r2_hi, r2_lo);
|
||||
// r4 = r2 * r2
|
||||
Packet r4_hi, r4_lo;
|
||||
twoprod(r2_hi, r2_lo, r2_hi, r2_lo, r4_hi, r4_lo);
|
||||
|
||||
// Evaluate Q(r^2) in working precision. We evaluate it in two parts
|
||||
// (even and odd in r^2) to improve instruction level parallelism.
|
||||
Packet q_even = pmadd(q12, r4_hi, q8);
|
||||
Packet q_odd = pmadd(q10, r4_hi, q6);
|
||||
q_even = pmadd(q_even, r4_hi, q4);
|
||||
q_odd = pmadd(q_odd, r4_hi, q2);
|
||||
q_even = pmadd(q_even, r4_hi, q0);
|
||||
Packet q = pmadd(q_odd, r2_hi, q_even);
|
||||
|
||||
// Now evaluate the low order terms of P(x) in double word precision.
|
||||
// In the following, due to the increasing magnitude of the coefficients
|
||||
// and r being constrained to [-0.5, 0.5] we can use fast_twosum instead
|
||||
// of the slower twosum.
|
||||
// Q(r^2) * r^2
|
||||
Packet p_hi, p_lo;
|
||||
twoprod(r2_hi, r2_lo, q, p_hi, p_lo);
|
||||
// Q(r^2) * r^2 + C
|
||||
Packet p1_hi, p1_lo;
|
||||
fast_twosum(C_hi, C_lo, p_hi, p_lo, p1_hi, p1_lo);
|
||||
// (Q(r^2) * r^2 + C) * r^2
|
||||
Packet p2_hi, p2_lo;
|
||||
twoprod(r2_hi, r2_lo, p1_hi, p1_lo, p2_hi, p2_lo);
|
||||
// ((Q(r^2) * r^2 + C) * r^2 + 1)
|
||||
Packet p3_hi, p3_lo;
|
||||
fast_twosum(one, p2_hi, p2_lo, p3_hi, p3_lo);
|
||||
|
||||
// log(z) ~= ((Q(r^2) * r^2 + C) * r^2 + 1) * r
|
||||
twoprod(p3_hi, p3_lo, r_hi, r_lo, log2_x_hi, log2_x_lo);
|
||||
}
|
||||
};
|
||||
|
||||
// This function computes exp2(x) (i.e. 2**x).
|
||||
template <typename Scalar>
|
||||
struct fast_accurate_exp2 {
|
||||
@@ -1168,8 +1304,75 @@ struct fast_accurate_exp2<float> {
|
||||
// to gain some instruction level parallelism.
|
||||
Packet x2 = pmul(x,x);
|
||||
Packet p_even = pmadd(p4, x2, p2);
|
||||
p_even = pmadd(p_even, x2, p0);
|
||||
Packet p_odd = pmadd(p3, x2, p1);
|
||||
p_even = pmadd(p_even, x2, p0);
|
||||
Packet p = pmadd(p_odd, x, p_even);
|
||||
|
||||
// Evaluate the remaining terms of Q(x) with extra precision using
|
||||
// double word arithmetic.
|
||||
Packet p_hi, p_lo;
|
||||
// x * p(x)
|
||||
twoprod(p, x, p_hi, p_lo);
|
||||
// C + x * p(x)
|
||||
Packet q1_hi, q1_lo;
|
||||
twosum(p_hi, p_lo, C_hi, C_lo, q1_hi, q1_lo);
|
||||
// x * (C + x * p(x))
|
||||
Packet q2_hi, q2_lo;
|
||||
twoprod(q1_hi, q1_lo, x, q2_hi, q2_lo);
|
||||
// 1 + x * (C + x * p(x))
|
||||
Packet q3_hi, q3_lo;
|
||||
// Since |q2_hi| <= sqrt(2)-1 < 1, we can use fast_twosum
|
||||
// for adding it to unity here.
|
||||
fast_twosum(one, q2_hi, q3_hi, q3_lo);
|
||||
return padd(q3_hi, padd(q2_lo, q3_lo));
|
||||
}
|
||||
};
|
||||
|
||||
// in [-0.5;0.5] with a relative accuracy of 1 ulp.
|
||||
// The minimax polynomial used was calculated using the Sollya tool.
|
||||
// See sollya.org.
|
||||
template <>
|
||||
struct fast_accurate_exp2<double> {
|
||||
template <typename Packet>
|
||||
EIGEN_STRONG_INLINE
|
||||
Packet operator()(const Packet& x) {
|
||||
// This function approximates exp2(x) by a degree 10 polynomial of the form
|
||||
// Q(x) = 1 + x * (C + x * P(x)), where the degree 8 polynomial P(x) is evaluated in
|
||||
// single precision, and the remaining steps are evaluated with extra precision using
|
||||
// double word arithmetic. C is an extra precise constant stored as a double word.
|
||||
//
|
||||
// The polynomial coefficients were calculated using Sollya commands:
|
||||
// > n = 11;
|
||||
// > f = 2^x;
|
||||
// > interval = [-0.5;0.5];
|
||||
// > p = fpminimax(f,n,[|1,DD,double...|],interval,relative,floating);
|
||||
|
||||
const Packet p9 = pset1<Packet>(4.431642109085495276e-10);
|
||||
const Packet p8 = pset1<Packet>(7.073829923303358410e-9);
|
||||
const Packet p7 = pset1<Packet>(1.017822306737031311e-7);
|
||||
const Packet p6 = pset1<Packet>(1.321543498017646657e-6);
|
||||
const Packet p5 = pset1<Packet>(1.525273342728892877e-5);
|
||||
const Packet p4 = pset1<Packet>(1.540353045780084423e-4);
|
||||
const Packet p3 = pset1<Packet>(1.333355814685869807e-3);
|
||||
const Packet p2 = pset1<Packet>(9.618129107593478832e-3);
|
||||
const Packet p1 = pset1<Packet>(5.550410866481961247e-2);
|
||||
const Packet p0 = pset1<Packet>(0.240226506959101332);
|
||||
const Packet C_hi = pset1<Packet>(0.693147180559945286);
|
||||
const Packet C_lo = pset1<Packet>(4.81927865669806721e-17);
|
||||
const Packet one = pset1<Packet>(1.0);
|
||||
|
||||
// Evaluate P(x) in working precision.
|
||||
// We evaluate even and odd parts of the polynomial separately
|
||||
// to gain some instruction level parallelism.
|
||||
Packet x2 = pmul(x,x);
|
||||
Packet p_even = pmadd(p8, x2, p6);
|
||||
Packet p_odd = pmadd(p9, x2, p7);
|
||||
p_even = pmadd(p_even, x2, p4);
|
||||
p_odd = pmadd(p_odd, x2, p5);
|
||||
p_even = pmadd(p_even, x2, p2);
|
||||
p_odd = pmadd(p_odd, x2, p3);
|
||||
p_even = pmadd(p_even, x2, p0);
|
||||
p_odd = pmadd(p_odd, x2, p1);
|
||||
Packet p = pmadd(p_odd, x, p_even);
|
||||
|
||||
// Evaluate the remaining terms of Q(x) with extra precision using
|
||||
@@ -1241,7 +1444,6 @@ EIGEN_STRONG_INLINE Packet generic_pow_impl(const Packet& x, const Packet& y) {
|
||||
// Since r_z is in [-0.5;0.5], we compute the first factor to high accuracy
|
||||
// using a specialized algorithm. Multiplication by the second factor can
|
||||
// be done exactly using pldexp(), since it is an integer power of 2.
|
||||
// Packet e_r = fast_accurate_exp2<Scalar>()(r_z);
|
||||
const Packet e_r = fast_accurate_exp2<Scalar>()(r_z);
|
||||
return pldexp(e_r, n_z);
|
||||
}
|
||||
@@ -1278,8 +1480,8 @@ Packet generic_pow(const Packet& x, const Packet& y) {
|
||||
const Packet y_is_nan = pandnot(ptrue(y), pcmp_eq(y, y));
|
||||
const Packet abs_y_is_inf = pcmp_eq(pabs(y), cst_pos_inf);
|
||||
EIGEN_CONSTEXPR Scalar huge_exponent =
|
||||
(std::numeric_limits<Scalar>::max_exponent * Scalar(EIGEN_LN2)) /
|
||||
std::numeric_limits<Scalar>::epsilon();
|
||||
(NumTraits<Scalar>::max_exponent() * Scalar(EIGEN_LN2)) /
|
||||
NumTraits<Scalar>::epsilon();
|
||||
const Packet abs_y_is_huge = pcmp_le(pset1<Packet>(huge_exponent), pabs(y));
|
||||
|
||||
// Predicates for whether y is integer and/or even.
|
||||
|
||||
@@ -63,10 +63,38 @@ struct half;
|
||||
|
||||
namespace half_impl {
|
||||
|
||||
#if !defined(EIGEN_HAS_GPU_FP16)
|
||||
// We want to use the __half_raw struct from the HIP header file only during the device compile phase.
|
||||
// This is required because of a quirk in the way TensorFlow GPU builds are done.
|
||||
// When compiling TensorFlow source code with GPU support, files that
|
||||
// * contain GPU kernels (i.e. *.cu.cc files) are compiled via hipcc
|
||||
// * do not contain GPU kernels ( i.e. *.cc files) are compiled via gcc (typically)
|
||||
//
|
||||
// Tensorflow uses the Eigen::half type as its FP16 type, and there are functions that
|
||||
// * are defined in a file that gets compiled via hipcc AND
|
||||
// * have Eigen::half as a pass-by-value argument AND
|
||||
// * are called in a file that gets compiled via gcc
|
||||
//
|
||||
// In the scenario described above the caller and callee will see different versions
|
||||
// of the Eigen::half base class __half_raw, and they will be compiled by different compilers
|
||||
//
|
||||
// There appears to be an ABI mismatch between gcc and clang (which is called by hipcc) that results in
|
||||
// the callee getting corrupted values for the Eigen::half argument.
|
||||
//
|
||||
// Making the host side compile phase of hipcc use the same Eigen::half impl, as the gcc compile, resolves
|
||||
// this error, and hence the following convoluted #if condition
|
||||
#if !defined(EIGEN_HAS_GPU_FP16) || !defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
// Make our own __half_raw definition that is similar to CUDA's.
|
||||
struct __half_raw {
|
||||
#if (defined(EIGEN_HAS_GPU_FP16) && !defined(EIGEN_GPU_COMPILE_PHASE))
|
||||
// Eigen::half can be used as the datatype for shared memory declarations (in Eigen and TF)
|
||||
// The element type for shared memory cannot have non-trivial constructors
|
||||
// and hence the following special casing (which skips the zero-initilization).
|
||||
// Note that this check gets done even in the host compilation phase, and
|
||||
// hence the need for this
|
||||
EIGEN_DEVICE_FUNC __half_raw() {}
|
||||
#else
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR __half_raw() : x(0) {}
|
||||
#endif
|
||||
#if defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC)
|
||||
explicit EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR __half_raw(numext::uint16_t raw) : x(numext::bit_cast<__fp16>(raw)) {
|
||||
}
|
||||
@@ -115,7 +143,10 @@ struct half : public half_impl::half_base {
|
||||
|
||||
// Writing this out as separate #if-else blocks to make the code easier to follow
|
||||
// The same applies to most #if-else blocks in this file
|
||||
#if !defined(EIGEN_HAS_GPU_FP16)
|
||||
#if !defined(EIGEN_HAS_GPU_FP16) || !defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
// Use the same base class for the following two scenarios
|
||||
// * when compiling without GPU support enabled
|
||||
// * during host compile phase when compiling with GPU support enabled
|
||||
typedef half_impl::__half_raw __half_raw;
|
||||
#elif defined(EIGEN_HAS_HIP_FP16)
|
||||
// Nothing to do here
|
||||
@@ -147,7 +178,7 @@ struct half : public half_impl::half_base {
|
||||
explicit EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR half(bool b)
|
||||
: half_impl::half_base(half_impl::raw_uint16_to_half(b ? 0x3c00 : 0)) {}
|
||||
template<class T>
|
||||
explicit EIGEN_DEVICE_FUNC half(const T& val)
|
||||
explicit EIGEN_DEVICE_FUNC half(T val)
|
||||
: half_impl::half_base(half_impl::float_to_half_rtne(static_cast<float>(val))) {}
|
||||
explicit EIGEN_DEVICE_FUNC half(float f)
|
||||
: half_impl::half_base(half_impl::float_to_half_rtne(f)) {}
|
||||
@@ -161,6 +192,14 @@ struct half : public half_impl::half_base {
|
||||
EIGEN_DEVICE_FUNC operator float() const { // NOLINT: Allow implicit conversion to float, because it is lossless.
|
||||
return half_impl::half_to_float(*this);
|
||||
}
|
||||
|
||||
#if defined(EIGEN_HAS_GPU_FP16) && !defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
EIGEN_DEVICE_FUNC operator __half() const {
|
||||
::__half_raw hr;
|
||||
hr.x = x;
|
||||
return __half(hr);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
} // end namespace Eigen
|
||||
@@ -426,6 +465,28 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator / (const half& a, Index b) {
|
||||
return half(static_cast<float>(a) / static_cast<float>(b));
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator++(half& a) {
|
||||
a += half(1);
|
||||
return a;
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator--(half& a) {
|
||||
a -= half(1);
|
||||
return a;
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator++(half& a, int) {
|
||||
half original_value = a;
|
||||
++a;
|
||||
return original_value;
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator--(half& a, int) {
|
||||
half original_value = a;
|
||||
--a;
|
||||
return original_value;
|
||||
}
|
||||
|
||||
// Conversion routines, including fallbacks for the host or older CUDA.
|
||||
// Note that newer Intel CPUs (Haswell or newer) have vectorized versions of
|
||||
// these in hardware. If we need more performance on older/other CPUs, they are
|
||||
@@ -657,9 +718,6 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half floor(const half& a) {
|
||||
return half(::floorf(float(a)));
|
||||
#endif
|
||||
}
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half rint(const half& a) {
|
||||
return half(::rintf(float(a)));
|
||||
}
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half ceil(const half& a) {
|
||||
#if (EIGEN_CUDA_SDK_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 300) || \
|
||||
defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
@@ -668,6 +726,15 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half ceil(const half& a) {
|
||||
return half(::ceilf(float(a)));
|
||||
#endif
|
||||
}
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half rint(const half& a) {
|
||||
return half(::rintf(float(a)));
|
||||
}
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half round(const half& a) {
|
||||
return half(::roundf(float(a)));
|
||||
}
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half fmod(const half& a, const half& b) {
|
||||
return half(::fmodf(float(a), float(b)));
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half (min)(const half& a, const half& b) {
|
||||
#if (defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 530) || \
|
||||
@@ -757,19 +824,6 @@ template<> struct NumTraits<Eigen::half>
|
||||
#pragma pop_macro("EIGEN_CONSTEXPR")
|
||||
#endif
|
||||
|
||||
namespace std {
|
||||
|
||||
#if __cplusplus > 199711L
|
||||
template <>
|
||||
struct hash<Eigen::half> {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::size_t operator()(const Eigen::half& a) const {
|
||||
return static_cast<std::size_t>(a.x);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
} // end namespace std
|
||||
|
||||
namespace Eigen {
|
||||
namespace numext {
|
||||
|
||||
@@ -822,19 +876,23 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC uint16_t bit_cast<uint16_t, Eigen::half>(c
|
||||
#if defined(EIGEN_HAS_CUDA_FP16) && EIGEN_CUDA_SDK_VER >= 90000
|
||||
|
||||
__device__ EIGEN_STRONG_INLINE Eigen::half __shfl_sync(unsigned mask, Eigen::half var, int srcLane, int width=warpSize) {
|
||||
return static_cast<Eigen::half>(__shfl_sync(mask, static_cast<__half>(var), srcLane, width));
|
||||
const __half h = var;
|
||||
return static_cast<Eigen::half>(__shfl_sync(mask, h, srcLane, width));
|
||||
}
|
||||
|
||||
__device__ EIGEN_STRONG_INLINE Eigen::half __shfl_up_sync(unsigned mask, Eigen::half var, unsigned int delta, int width=warpSize) {
|
||||
return static_cast<Eigen::half>(__shfl_up_sync(mask, static_cast<__half>(var), delta, width));
|
||||
const __half h = var;
|
||||
return static_cast<Eigen::half>(__shfl_up_sync(mask, h, delta, width));
|
||||
}
|
||||
|
||||
__device__ EIGEN_STRONG_INLINE Eigen::half __shfl_down_sync(unsigned mask, Eigen::half var, unsigned int delta, int width=warpSize) {
|
||||
return static_cast<Eigen::half>(__shfl_down_sync(mask, static_cast<__half>(var), delta, width));
|
||||
const __half h = var;
|
||||
return static_cast<Eigen::half>(__shfl_down_sync(mask, h, delta, width));
|
||||
}
|
||||
|
||||
__device__ EIGEN_STRONG_INLINE Eigen::half __shfl_xor_sync(unsigned mask, Eigen::half var, int laneMask, int width=warpSize) {
|
||||
return static_cast<Eigen::half>(__shfl_xor_sync(mask, static_cast<__half>(var), laneMask, width));
|
||||
const __half h = var;
|
||||
return static_cast<Eigen::half>(__shfl_xor_sync(mask, h, laneMask, width));
|
||||
}
|
||||
|
||||
#else // HIP or CUDA SDK < 9.0
|
||||
@@ -870,4 +928,15 @@ EIGEN_STRONG_INLINE __device__ Eigen::half __ldg(const Eigen::half* ptr) {
|
||||
}
|
||||
#endif // __ldg
|
||||
|
||||
#if EIGEN_HAS_STD_HASH
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<Eigen::half> {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::size_t operator()(const Eigen::half& a) const {
|
||||
return static_cast<std::size_t>(Eigen::numext::bit_cast<Eigen::numext::uint16_t>(a));
|
||||
}
|
||||
};
|
||||
} // end namespace std
|
||||
#endif
|
||||
|
||||
#endif // EIGEN_HALF_H
|
||||
|
||||
@@ -15,12 +15,16 @@ namespace Eigen {
|
||||
namespace internal {
|
||||
|
||||
// Read-only data cached load available.
|
||||
#if defined(EIGEN_HIP_DEVICE_COMPILE) || EIGEN_CUDA_ARCH >= 350
|
||||
#if defined(EIGEN_HIP_DEVICE_COMPILE) || (defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 350)
|
||||
#define EIGEN_GPU_HAS_LDG 1
|
||||
#endif
|
||||
|
||||
// FP16 math available.
|
||||
#if defined(EIGEN_HIP_DEVICE_COMPILE) || EIGEN_CUDA_ARCH >= 530
|
||||
#if (defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 530)
|
||||
#define EIGEN_CUDA_HAS_FP16_ARITHMETIC 1
|
||||
#endif
|
||||
|
||||
#if defined(EIGEN_HIP_DEVICE_COMPILE) || defined(EIGEN_CUDA_HAS_FP16_ARITHMETIC)
|
||||
#define EIGEN_GPU_HAS_FP16_ARITHMETIC 1
|
||||
#endif
|
||||
|
||||
@@ -603,7 +607,8 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void pstoreu(Eigen::half* to,
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE half2 ploadt_ro_aligned(
|
||||
const Eigen::half* from) {
|
||||
#if defined(EIGEN_GPU_HAS_LDG)
|
||||
return __ldg((const half2*)from);
|
||||
// Input is guaranteed to be properly aligned.
|
||||
return __ldg(reinterpret_cast<const half2*>(from));
|
||||
#else
|
||||
return combine_half(*(from+0), *(from+1));
|
||||
#endif
|
||||
@@ -922,7 +927,7 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pexpm1(const half2& a) {
|
||||
return __floats2half2_rn(r1, r2);
|
||||
}
|
||||
|
||||
#if (EIGEN_CUDA_SDK_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 530) || \
|
||||
#if (EIGEN_CUDA_SDK_VER >= 80000 && defined(EIGEN_CUDA_HAS_FP16_ARITHMETIC)) || \
|
||||
defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
@@ -1033,7 +1038,7 @@ EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet4h2
|
||||
ploadt_ro<Packet4h2, Aligned>(const Eigen::half* from) {
|
||||
#if defined(EIGEN_GPU_HAS_LDG)
|
||||
Packet4h2 r;
|
||||
r = __ldg((const Packet4h2*)from);
|
||||
r = __ldg(reinterpret_cast<const Packet4h2*>(from));
|
||||
return r;
|
||||
#else
|
||||
Packet4h2 r;
|
||||
@@ -1226,7 +1231,7 @@ plset<Packet4h2>(const Eigen::half& a) {
|
||||
p_alias[3] = __halves2half2(__hadd(a, __float2half(6.0f)),
|
||||
__hadd(a, __float2half(7.0f)));
|
||||
return r;
|
||||
#elif EIGEN_CUDA_ARCH >= 530
|
||||
#elif defined(EIGEN_CUDA_HAS_FP16_ARITHMETIC)
|
||||
Packet4h2 r;
|
||||
half2* r_alias = reinterpret_cast<half2*>(&r);
|
||||
|
||||
@@ -1478,7 +1483,7 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Eigen::half predux_max<Packet4h2>(
|
||||
predux_max(a_alias[3]));
|
||||
__half first = predux_max(m0);
|
||||
__half second = predux_max(m1);
|
||||
#if EIGEN_CUDA_ARCH >= 530
|
||||
#if defined(EIGEN_CUDA_HAS_FP16_ARITHMETIC)
|
||||
return (__hgt(first, second) ? first : second);
|
||||
#else
|
||||
float ffirst = __half2float(first);
|
||||
@@ -1497,7 +1502,7 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Eigen::half predux_min<Packet4h2>(
|
||||
predux_min(a_alias[3]));
|
||||
__half first = predux_min(m0);
|
||||
__half second = predux_min(m1);
|
||||
#if EIGEN_CUDA_ARCH >= 530
|
||||
#if defined(EIGEN_CUDA_HAS_FP16_ARITHMETIC)
|
||||
return (__hlt(first, second) ? first : second);
|
||||
#else
|
||||
float ffirst = __half2float(first);
|
||||
@@ -1669,6 +1674,7 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pmax<half2>(const half2& a,
|
||||
#endif // defined(EIGEN_HAS_CUDA_FP16) || defined(EIGEN_HAS_HIP_FP16)
|
||||
|
||||
#undef EIGEN_GPU_HAS_LDG
|
||||
#undef EIGEN_CUDA_HAS_FP16_ARITHMETIC
|
||||
#undef EIGEN_GPU_HAS_FP16_ARITHMETIC
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
1079
Eigen/src/Core/arch/NEON/Kernels.h
Normal file
1079
Eigen/src/Core/arch/NEON/Kernels.h
Normal file
File diff suppressed because it is too large
Load Diff
555
Eigen/src/Core/arch/NEON/MatrixProduct.h
Normal file
555
Eigen/src/Core/arch/NEON/MatrixProduct.h
Normal file
@@ -0,0 +1,555 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2021 Everton Constantino (everton.constantino@hotmail.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_MATRIX_PRODUCT_NEON_H
|
||||
#define EIGEN_MATRIX_PRODUCT_NEON_H
|
||||
|
||||
#ifdef __DEBUG__
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
#ifndef __UNROLL__
|
||||
#define __UNROLL__ 8
|
||||
#endif
|
||||
|
||||
template<int Architecture, int CPU, typename LhsScalar, typename RhsScalar>
|
||||
constexpr int SHAPES_COUNT = 16;
|
||||
|
||||
constexpr int SHAPES_DIMENSION = 6;
|
||||
constexpr int SHAPES_LHS_DIMENSION = 0;
|
||||
constexpr int SHAPES_DEP_DIMENSION = 1;
|
||||
constexpr int SHAPES_RHS_DIMENSION = 2;
|
||||
constexpr int SHAPES_RHS_POINTER = 3;
|
||||
constexpr int SHAPES_LHS_POINTER = 4;
|
||||
constexpr int SHAPES_DEP_POINTER = 5;
|
||||
constexpr int SHAPES_POINTER_END = -1;
|
||||
|
||||
template<int Architecture, int CPU, typename Scalar, bool isLhs>
|
||||
constexpr int PACK_SHAPES_COUNT = 2;
|
||||
|
||||
template<int Architecture, int CPU, typename Scalar>
|
||||
constexpr int PACK_SHAPES_COUNT<Architecture, CPU, Scalar, true> = 4;
|
||||
|
||||
constexpr int PACK_SHAPES_DIMENSION = 3;
|
||||
constexpr int PACK_SHAPES_POINTER = 2;
|
||||
constexpr int PACK_SHAPES_END = -1;
|
||||
|
||||
template<typename Scalar>
|
||||
struct PacketMultiples
|
||||
{
|
||||
enum
|
||||
{
|
||||
half = unpacket_traits<typename packet_traits<Scalar>::half>::size,
|
||||
quarter = unpacket_traits<typename packet_traits<Scalar>::half>::size // Is this used?
|
||||
};
|
||||
};
|
||||
|
||||
// lhs_progress x depth_progress x rhs_progress (depth_progress > 1 matrix ops) x pointer to next rhs_progress on the shapes map
|
||||
template<int Architecture, int CPU, typename LhsScalar, typename RhsScalar>
|
||||
constexpr int SHAPES[SHAPES_COUNT<Architecture, CPU, LhsScalar,RhsScalar>][SHAPES_DIMENSION] =
|
||||
{ /* 00 */{ 1, 1,1,SHAPES_POINTER_END, SHAPES_POINTER_END, SHAPES_POINTER_END},
|
||||
/* 01 */{PacketMultiples<RhsScalar>::half, 1,1, 0, 0, SHAPES_POINTER_END},
|
||||
/* 02 */{1*packet_traits<RhsScalar>::size, 1,1, 0, 1, SHAPES_POINTER_END},
|
||||
/* 03 */{1*packet_traits<RhsScalar>::size,__UNROLL__,1, 0, 1, 2},
|
||||
/* 04 */{2*packet_traits<RhsScalar>::size, 1,1, 0, 3, SHAPES_POINTER_END},
|
||||
/* 05 */{2*packet_traits<RhsScalar>::size,__UNROLL__,1, 0, 3, 4},
|
||||
/* 06 */{3*packet_traits<RhsScalar>::size, 1,1, 0, 5, SHAPES_POINTER_END},
|
||||
/* 07 */{3*packet_traits<RhsScalar>::size,__UNROLL__,1, 0, 5, 6},
|
||||
/* 08 */{ 1, 1,4, 7, SHAPES_POINTER_END, SHAPES_POINTER_END},
|
||||
/* 09 */{PacketMultiples<RhsScalar>::half, 1,4, 7, 8, SHAPES_POINTER_END},
|
||||
/* 10 */{1*packet_traits<RhsScalar>::size, 1,4, 7, 9, SHAPES_POINTER_END},
|
||||
/* 11 */{1*packet_traits<RhsScalar>::size,__UNROLL__,4, 7, 9, 10},
|
||||
/* 12 */{2*packet_traits<RhsScalar>::size, 1,4, 7, 11, SHAPES_POINTER_END},
|
||||
/* 13 */{2*packet_traits<RhsScalar>::size,__UNROLL__,4, 7, 11, 12},
|
||||
/* 14 */{3*packet_traits<RhsScalar>::size, 1,4, 7, 13, SHAPES_POINTER_END},
|
||||
/* 15 */{3*packet_traits<RhsScalar>::size,__UNROLL__,4, 7, 13, 14}};
|
||||
|
||||
// d1progress x d2progress
|
||||
template<int Architecture, int CPU, typename Scalar, bool isLhs>
|
||||
constexpr int PACK_SHAPES[PACK_SHAPES_COUNT<Architecture, CPU, Scalar, isLhs>][PACK_SHAPES_DIMENSION] =
|
||||
{{ 1, 1, PACK_SHAPES_END},
|
||||
{ 4, 1, 0}};
|
||||
|
||||
template<int Architecture, int CPU, typename Scalar>
|
||||
constexpr int PACK_SHAPES<Architecture, CPU, Scalar, true>[PACK_SHAPES_COUNT<Architecture, CPU, Scalar, true>][PACK_SHAPES_DIMENSION] =
|
||||
{{ 1, 1, PACK_SHAPES_END},
|
||||
{1*packet_traits<Scalar>::size, 1, 0},
|
||||
{2*packet_traits<Scalar>::size, 1, 1},
|
||||
{3*packet_traits<Scalar>::size, 1, 2}};
|
||||
|
||||
template<int Architecture, int CPU, typename Index, typename Scalar, bool isLhs, typename DataMapper, bool Conjugate, bool PanelMode, int StorageOrder, int M, int N>
|
||||
struct PackingOperator
|
||||
{
|
||||
EIGEN_STRONG_INLINE Scalar* operator()(Index d1Idx, Index d2Idx, Scalar *block, const DataMapper& data)
|
||||
{
|
||||
#ifdef __DEBUG__
|
||||
std::cout << M << "x" << N << " ( " << d1Idx << ", " << d2Idx <<") -> ( " << d1Idx + M << ", " << d2Idx + N << ") ";
|
||||
#endif
|
||||
Scalar *c = block;
|
||||
for(auto i = 0; i < M; i++)
|
||||
for(auto j = 0; j < N; j++)
|
||||
{
|
||||
if(isLhs)
|
||||
*c = data(d1Idx + i, d2Idx + j);
|
||||
else
|
||||
*c = data(d2Idx + j, d1Idx + i);
|
||||
#ifdef __DEBUG__
|
||||
std::cout << *c << " ";
|
||||
#endif
|
||||
c++;
|
||||
}
|
||||
#ifdef __DEBUG__
|
||||
std::cout << std::endl;
|
||||
#endif
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
template<int Architecture, int CPU, typename Index, typename Scalar, bool isLhs, typename DataMapper, bool Conjugate, bool PanelMode, int StorageOrder, int D1PROGRESS, int IDX>
|
||||
struct PackingInnerStruct
|
||||
{
|
||||
EIGEN_STRONG_INLINE Scalar* operator()(Index d1Idx, Index d2Idx, Scalar *block, const DataMapper& data, Index d1Size, Index d2Size, Index stride, Index offset)
|
||||
{
|
||||
constexpr auto d2Progress = PACK_SHAPES<Architecture, CPU, Scalar, isLhs>[IDX][1];
|
||||
PackingOperator<Architecture, CPU, Index, Scalar, isLhs, DataMapper, Conjugate, PanelMode, StorageOrder, D1PROGRESS, d2Progress> po;
|
||||
|
||||
for(;d2Idx + d2Progress <= d2Size; d2Idx+=d2Progress)
|
||||
{
|
||||
block = po(d1Idx, d2Idx, block, data);
|
||||
}
|
||||
|
||||
if(PACK_SHAPES<Architecture, CPU, Scalar, isLhs>[IDX-1][0] == D1PROGRESS)
|
||||
{
|
||||
PackingInnerStruct<Architecture, CPU, Index, Scalar, isLhs, DataMapper, Conjugate, PanelMode, StorageOrder, D1PROGRESS, IDX-1> pis;
|
||||
block = pis(d1Idx, d2Idx, block, data, d1Size, d2Size, stride, offset);
|
||||
}
|
||||
return block;
|
||||
}
|
||||
};
|
||||
|
||||
template<int Architecture, int CPU, typename Index, typename Scalar, bool isLhs, typename DataMapper, bool Conjugate, bool PanelMode, int StorageOrder, int D1PROGRESS>
|
||||
struct PackingInnerStruct<Architecture, CPU, Index, Scalar, isLhs, DataMapper, Conjugate, PanelMode, StorageOrder, D1PROGRESS, 0>
|
||||
{
|
||||
EIGEN_STRONG_INLINE Scalar* operator()(Index d1Idx, Index d2Idx, Scalar *block, const DataMapper& data, Index d1Size, Index d2Size, Index stride, Index offset)
|
||||
{
|
||||
constexpr auto d2Progress = PACK_SHAPES<Architecture, CPU, Scalar, isLhs>[0][1];
|
||||
for(;d2Idx + d2Progress <= d2Size; d2Idx+=d2Progress)
|
||||
{
|
||||
PackingOperator<Architecture, CPU, Index, Scalar, isLhs, DataMapper, Conjugate, PanelMode, StorageOrder, D1PROGRESS, d2Progress> po;
|
||||
block = po(d1Idx, d2Idx, block, data);
|
||||
}
|
||||
return block;
|
||||
}
|
||||
};
|
||||
|
||||
template<int Architecture, int CPU, typename Index, typename Scalar, bool isLhs, typename DataMapper, bool Conjugate, bool PanelMode, int StorageOrder, int PACK_SHAPE_IDX>
|
||||
struct PackingStruct
|
||||
{
|
||||
PackingStruct<Architecture, CPU, Index, Scalar, isLhs, DataMapper, Conjugate, PanelMode, StorageOrder, PACK_SHAPES<Architecture, CPU, Scalar, isLhs>[PACK_SHAPE_IDX][PACK_SHAPES_POINTER]> ps;
|
||||
|
||||
EIGEN_STRONG_INLINE Scalar* operator()(Index d1Idx, Scalar *block, const DataMapper& data, Index d1Size, Index d2Size, Index stride, Index offset)
|
||||
{
|
||||
constexpr auto d1Progress = PACK_SHAPES<Architecture, CPU, Scalar, isLhs>[PACK_SHAPE_IDX][0];
|
||||
|
||||
for(; d1Idx + d1Progress <= d1Size; d1Idx += d1Progress)
|
||||
{
|
||||
PackingInnerStruct<Architecture, CPU, Index, Scalar, isLhs, DataMapper, Conjugate, PanelMode, StorageOrder, d1Progress, PACK_SHAPE_IDX> pis;
|
||||
block = pis(d1Idx, 0, block, data, d1Size, d2Size, stride, offset);
|
||||
}
|
||||
return ps(d1Idx, block, data, d1Size, d2Size, stride, offset);
|
||||
}
|
||||
};
|
||||
|
||||
template<int Architecture, int CPU, typename Index, typename Scalar, bool isLhs, typename DataMapper, bool Conjugate, bool PanelMode, int StorageOrder>
|
||||
struct PackingStruct<Architecture, CPU, Index, Scalar, isLhs, DataMapper, Conjugate, PanelMode, StorageOrder, -1>
|
||||
{
|
||||
EIGEN_STRONG_INLINE Scalar* operator()(Index, Scalar *block, const DataMapper&, Index, Index, Index, Index) { return block; }
|
||||
};
|
||||
|
||||
template<int Architecture, int CPU, typename Index, typename Scalar, typename DataMapper, bool Conjugate, bool PanelMode, int StorageOrder>
|
||||
struct lhs_pack
|
||||
{
|
||||
EIGEN_STRONG_INLINE void operator()(Scalar *blockA, const DataMapper &lhs, Index depth, Index rows, Index stride, Index offset)
|
||||
{
|
||||
PackingStruct<Architecture, CPU, Index, Scalar, true, DataMapper, Conjugate, PanelMode, StorageOrder, PACK_SHAPES_COUNT<Architecture, CPU, Scalar, true>-1> ps;
|
||||
ps(0, blockA, lhs, rows, depth, stride, offset);
|
||||
}
|
||||
};
|
||||
|
||||
template<int Architecture, int CPU, typename Index, typename Scalar, typename DataMapper, bool Conjugate, bool PanelMode, int StorageOrder>
|
||||
struct rhs_pack
|
||||
{
|
||||
EIGEN_STRONG_INLINE void operator()(Scalar *blockB, const DataMapper &rhs, Index depth, Index cols, Index stride, Index offset)
|
||||
{
|
||||
PackingStruct<Architecture, CPU, Index, Scalar, false, DataMapper, Conjugate, PanelMode, StorageOrder, PACK_SHAPES_COUNT<Architecture, CPU, Scalar, false>-1> ps;
|
||||
ps(0, blockB, rhs, cols, depth, stride, offset);
|
||||
}
|
||||
};
|
||||
|
||||
template<int Architecture, int CPU, typename Index, typename Scalar, typename DataMapper, bool isLhs, int IDX>
|
||||
struct PackMapCalculator
|
||||
{
|
||||
PackMapCalculator<Architecture, CPU, Index, Scalar, DataMapper, isLhs, PACK_SHAPES<Architecture, CPU, Scalar, isLhs>[IDX][PACK_SHAPES_POINTER]> pmc;
|
||||
EIGEN_STRONG_INLINE Index getPosition(Index pos, Index d2Size)
|
||||
{
|
||||
constexpr auto d1Progress = PACK_SHAPES<Architecture, CPU, Scalar, isLhs>[IDX][0];
|
||||
Index v = (pos / d1Progress) * d1Progress;
|
||||
return v*d2Size + pmc.getPosition(pos - v, d2Size);
|
||||
}
|
||||
};
|
||||
|
||||
template<int Architecture, int CPU, typename Index, typename Scalar, typename DataMapper, bool isLhs>
|
||||
struct PackMapCalculator<Architecture, CPU, Index, Scalar, DataMapper, isLhs, -1>
|
||||
{
|
||||
EIGEN_STRONG_INLINE Index getPosition(Index, Index) { return Index(0); }
|
||||
};
|
||||
|
||||
template<int Architecture, int CPU, typename Index, typename Scalar, typename DataMapper, bool isLhs>
|
||||
struct PackMap
|
||||
{
|
||||
const Scalar *pBase;
|
||||
const Scalar *pCur;
|
||||
Index stride;
|
||||
Index offset;
|
||||
Index d2Size;
|
||||
PackMapCalculator<Architecture, CPU, Index, Scalar, DataMapper, isLhs, PACK_SHAPES_COUNT<Architecture, CPU, Scalar, isLhs>-1> pmc;
|
||||
|
||||
PackMap(const Scalar *base, Index d2Size, Index stride, Index offset) : pBase(base), pCur(base), d2Size(d2Size), stride(stride), offset(offset) {}
|
||||
|
||||
EIGEN_STRONG_INLINE void resetCur() { pCur = pBase; }
|
||||
EIGEN_STRONG_INLINE void updateBase() { pBase = pCur; }
|
||||
EIGEN_STRONG_INLINE void moveTo(Index p1) { pCur = pBase + pmc.getPosition(p1, d2Size); }
|
||||
EIGEN_STRONG_INLINE void advance(Index progress) { pCur += progress; }
|
||||
|
||||
template<int D1Progress=-1, int D2Progress=-1>
|
||||
EIGEN_STRONG_INLINE void prefetch(Index amnt)
|
||||
{
|
||||
#ifdef __ENABLE_PREFETCH__
|
||||
internal::prefetch(pCur + amnt);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
template<int Architecture, int CPU, typename Scalar, typename ResScalar, typename DataMapper, int M, int N>
|
||||
struct Accumulator
|
||||
{
|
||||
Scalar dt[M][N];
|
||||
|
||||
EIGEN_STRONG_INLINE void zero()
|
||||
{
|
||||
for(auto i = 0; i < M; i++)
|
||||
{
|
||||
for(auto j = 0; j < N; j++)
|
||||
{
|
||||
dt[i][j] = Scalar(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<int LhsProgress=-1, int DepthProgress=-1, int RhsProgress=-1>
|
||||
EIGEN_STRONG_INLINE void prefetch(const DataMapper&, Index, Index) {}
|
||||
|
||||
template<typename ResPacket>
|
||||
EIGEN_STRONG_INLINE void scale(ResScalar alpha, const ResPacket& pAlpha)
|
||||
{
|
||||
for(auto i = 0; i < M; i++)
|
||||
{
|
||||
for(auto j = 0; j < N; j++)
|
||||
{
|
||||
dt[i][j] *= alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ResPacket>
|
||||
EIGEN_STRONG_INLINE void store(const DataMapper& dest, Index row, Index col, ResScalar alpha, const ResPacket& pAlpha)
|
||||
{
|
||||
for(auto i = 0; i < M; i++)
|
||||
{
|
||||
for(auto j = 0; j < N; j++)
|
||||
{
|
||||
dest(row + i, col + j) += alpha*dt[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<int Architecture, int CPU, typename Index, typename LhsScalar, typename LhsPackMap, typename RhsScalar, typename RhsPackMap, typename AccScalar, typename ResScalar, typename Accumulator, int M, int K, int N>
|
||||
struct MicroKernel
|
||||
{
|
||||
EIGEN_STRONG_INLINE void operator()(LhsPackMap& lhsPackMap,
|
||||
RhsPackMap& rhsPackMap,
|
||||
Index rowIdx, Index colIdx, Index depthIdx,
|
||||
Accumulator& acc)
|
||||
{
|
||||
const RhsScalar *pRhs = rhsPackMap.pCur;
|
||||
for(auto i = 0; i < N; i++)
|
||||
{
|
||||
const LhsScalar *pLhs = lhsPackMap.pCur;
|
||||
for(auto j = 0; j < M; j++)
|
||||
{
|
||||
acc.dt[j][i] += pRhs[i]*pLhs[j];
|
||||
}
|
||||
}
|
||||
lhsPackMap.advance(M*K);
|
||||
rhsPackMap.advance(K*N);
|
||||
};
|
||||
};
|
||||
|
||||
template<int Architecture, int CPU, typename Index, typename LhsScalar, typename LhsPackMap, typename RhsScalar, typename RhsPackMap, typename AccScalar, typename ResScalar, typename ResPacket, typename DataMapper, typename AccumulatorType, int RHS_SHAPE_IDX, int LHS_SHAPE_IDX, int IDX>
|
||||
struct DepthLoopStruct
|
||||
{
|
||||
static constexpr auto PREVIOUS = SHAPES<Architecture, CPU, LhsScalar, RhsScalar>[IDX][SHAPES_DEP_POINTER];
|
||||
|
||||
DepthLoopStruct<Architecture, CPU, Index, LhsScalar, LhsPackMap, RhsScalar, RhsPackMap, AccScalar, ResScalar, ResPacket, DataMapper, AccumulatorType, RHS_SHAPE_IDX, LHS_SHAPE_IDX, PREVIOUS> depthLS;
|
||||
|
||||
EIGEN_STRONG_INLINE void operator()(Index rowIdx, Index colIdx, Index depthIdx, const DataMapper& res, AccumulatorType& acc,
|
||||
Index rows, Index depth, Index cols, ResScalar alpha, const ResPacket& pAlpha, LhsPackMap& lhsPackMap, RhsPackMap& rhsPackMap)
|
||||
{
|
||||
constexpr auto rhsProgress = SHAPES<Architecture, CPU, LhsScalar, RhsScalar>[RHS_SHAPE_IDX][SHAPES_RHS_DIMENSION];
|
||||
constexpr auto lhsProgress = SHAPES<Architecture, CPU, LhsScalar, RhsScalar>[LHS_SHAPE_IDX][SHAPES_LHS_DIMENSION];
|
||||
constexpr auto depthProgress = SHAPES<Architecture, CPU, LhsScalar, RhsScalar>[IDX][SHAPES_DEP_DIMENSION];
|
||||
|
||||
//typedef Accumulator<Architecture, CPU, AccScalar, ResScalar, DataMapper, lhsProgress, rhsProgress> AccumulatorType;
|
||||
|
||||
MicroKernel<Architecture, CPU, Index, LhsScalar, LhsPackMap, RhsScalar, RhsPackMap, AccScalar, ResScalar, AccumulatorType, lhsProgress, depthProgress, rhsProgress> mkt;
|
||||
//AccumulatorType acc;
|
||||
|
||||
//acc.zero();
|
||||
|
||||
acc.template prefetch<lhsProgress, depthProgress, rhsProgress>(res, rowIdx, colIdx);
|
||||
|
||||
lhsPackMap.template prefetch<lhsProgress, depthProgress>(0);
|
||||
rhsPackMap.template prefetch<rhsProgress, depthProgress>(0);
|
||||
|
||||
for(; depthIdx + depthProgress <= depth; depthIdx+=depthProgress)
|
||||
{
|
||||
#ifdef __DEBUG__
|
||||
auto M = lhsProgress;
|
||||
auto K = depthProgress;
|
||||
auto N = rhsProgress;
|
||||
std::cout << "Kernel " << M << " x " << K << " x " << N << " @ " << rowIdx << ", " << depthIdx << ", " << colIdx << std::endl;
|
||||
std::cout << "LHS ";
|
||||
for(auto i = 0; i < M; i++)
|
||||
{
|
||||
for(auto j = 0; j < K; j++)
|
||||
{
|
||||
std::cout << lhsPackMap.pCur[i*K + j] << " ";
|
||||
}
|
||||
}
|
||||
std::cout << std::endl << "RHS ";
|
||||
for(auto i = 0; i < K; i++)
|
||||
{
|
||||
for(auto j = 0; j < N; j++)
|
||||
{
|
||||
std::cout << rhsPackMap.pCur[i*N + j] << " ";
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
#endif
|
||||
mkt(lhsPackMap, rhsPackMap, rowIdx, colIdx, depthIdx, acc);
|
||||
}
|
||||
//acc.store(res, rowIdx, colIdx, alpha, pAlpha);
|
||||
|
||||
depthLS(rowIdx, colIdx, depthIdx, res, acc, rows, depth, cols, alpha, pAlpha, lhsPackMap, rhsPackMap);
|
||||
}
|
||||
};
|
||||
|
||||
template<int Architecture, int CPU, typename Index, typename LhsScalar, typename LhsPackMap, typename RhsScalar, typename RhsPackMap, typename AccScalar, typename ResScalar, typename ResPacket, typename DataMapper, typename AccumulatorType, int RHS_SHAPE_IDX, int LHS_SHAPE_IDX>
|
||||
struct DepthLoopStruct<Architecture, CPU, Index, LhsScalar, LhsPackMap, RhsScalar, RhsPackMap, AccScalar, ResScalar, ResPacket, DataMapper, AccumulatorType, RHS_SHAPE_IDX, LHS_SHAPE_IDX, -1>
|
||||
{
|
||||
EIGEN_STRONG_INLINE void operator()(Index, Index, Index, const DataMapper&, AccumulatorType&,
|
||||
Index, Index, Index, ResScalar, const ResPacket&, LhsPackMap&, RhsPackMap&) {}
|
||||
};
|
||||
|
||||
template<int Architecture, int CPU, typename Index, typename LhsScalar, typename LhsPackMap, typename RhsScalar, typename RhsPackMap, typename AccScalar, typename ResScalar, typename ResPacket, typename DataMapper, int RHS_SHAPE_IDX, int IDX>
|
||||
struct LhsLoopStruct
|
||||
{
|
||||
static constexpr auto PREVIOUS = SHAPES<Architecture, CPU, LhsScalar, RhsScalar>[IDX][SHAPES_LHS_POINTER];
|
||||
LhsLoopStruct<Architecture, CPU, Index, LhsScalar, LhsPackMap, RhsScalar, RhsPackMap, AccScalar, ResScalar, ResPacket, DataMapper, RHS_SHAPE_IDX, PREVIOUS> lhsLS;
|
||||
|
||||
EIGEN_STRONG_INLINE void operator()(Index rowIdx, int colIdx, const DataMapper& res,
|
||||
Index rows, Index depth, Index cols, ResScalar alpha, const ResPacket& pAlpha, LhsPackMap& lhsPackMap, RhsPackMap& rhsPackMap)
|
||||
{
|
||||
constexpr auto lhsProgress = SHAPES<Architecture, CPU, LhsScalar, RhsScalar>[IDX][SHAPES_LHS_DIMENSION];
|
||||
constexpr auto rhsProgress = SHAPES<Architecture, CPU, LhsScalar, RhsScalar>[IDX][SHAPES_RHS_DIMENSION];
|
||||
|
||||
typedef Accumulator<Architecture, CPU, AccScalar, ResScalar, DataMapper, lhsProgress, rhsProgress> AccumulatorType;
|
||||
|
||||
DepthLoopStruct<Architecture, CPU, Index, LhsScalar, LhsPackMap, RhsScalar, RhsPackMap, AccScalar, ResScalar, ResPacket, DataMapper, AccumulatorType, RHS_SHAPE_IDX, IDX, IDX> depthLS;
|
||||
|
||||
//rhsPackMap.resetCur();
|
||||
for(;rowIdx + lhsProgress <= rows; rowIdx+=lhsProgress)
|
||||
{
|
||||
rhsPackMap.resetCur();
|
||||
AccumulatorType acc;
|
||||
acc.zero();
|
||||
//lhsPackMap.moveTo(rowIdx);
|
||||
//rhsPackMap.moveTo(colIdx);
|
||||
|
||||
depthLS(rowIdx, colIdx, 0, res, acc, rows, depth, cols, alpha, pAlpha, lhsPackMap, rhsPackMap);
|
||||
acc.store(res, rowIdx, colIdx, alpha, pAlpha);
|
||||
}
|
||||
lhsLS(rowIdx, colIdx, res, rows, depth, cols, alpha, pAlpha, lhsPackMap, rhsPackMap);
|
||||
}
|
||||
};
|
||||
|
||||
template<int Architecture, int CPU, typename Index, typename LhsScalar, typename LhsPackMap, typename RhsScalar, typename RhsPackMap, typename AccScalar, typename ResScalar, typename ResPacket, typename DataMapper, int RHS_SHAPE_IDX>
|
||||
struct LhsLoopStruct<Architecture, CPU, Index, LhsScalar, LhsPackMap, RhsScalar, RhsPackMap, AccScalar, ResScalar, ResPacket, DataMapper, RHS_SHAPE_IDX, -1>
|
||||
{
|
||||
EIGEN_STRONG_INLINE void operator()(Index, Index, const DataMapper&,
|
||||
Index, Index, Index, ResScalar, const ResPacket&, LhsPackMap&, RhsPackMap&) {}
|
||||
};
|
||||
|
||||
template<int Architecture, int CPU, typename Index, typename LhsScalar, typename LhsPackMap, typename RhsScalar, typename RhsPackMap, typename AccScalar, typename ResScalar, typename ResPacket, typename DataMapper, int IDX>
|
||||
struct RhsLoopStruct
|
||||
{
|
||||
static constexpr auto PREVIOUS = SHAPES<Architecture, CPU, LhsScalar, RhsScalar>[IDX][SHAPES_RHS_POINTER];
|
||||
RhsLoopStruct<Architecture, CPU, Index, LhsScalar, LhsPackMap, RhsScalar, RhsPackMap, AccScalar, ResScalar, ResPacket, DataMapper, PREVIOUS> rhsLS;
|
||||
|
||||
EIGEN_STRONG_INLINE void operator()(Index colIdx, const DataMapper& res,
|
||||
Index rows, Index depth, Index cols, ResScalar alpha, const ResPacket& pAlpha, LhsPackMap& lhsPackMap, RhsPackMap& rhsPackMap)
|
||||
{
|
||||
constexpr auto rhsProgress = SHAPES<Architecture, CPU, LhsScalar, RhsScalar>[IDX][SHAPES_RHS_DIMENSION];
|
||||
|
||||
for(;colIdx + rhsProgress <= cols; colIdx+=rhsProgress)
|
||||
{
|
||||
LhsLoopStruct<Architecture, CPU, Index, LhsScalar, LhsPackMap, RhsScalar, RhsPackMap, AccScalar, ResScalar, ResPacket, DataMapper, IDX, IDX> lhsLS;
|
||||
lhsPackMap.resetCur();
|
||||
lhsLS(0, colIdx, res, rows, depth, cols, alpha, pAlpha, lhsPackMap, rhsPackMap);
|
||||
rhsPackMap.updateBase();
|
||||
}
|
||||
rhsLS(colIdx, res, rows, depth, cols, alpha, pAlpha, lhsPackMap, rhsPackMap);
|
||||
}
|
||||
};
|
||||
|
||||
template<int Architecture, int CPU, typename Index, typename LhsScalar, typename LhsPackMap, typename RhsScalar, typename RhsPackMap, typename AccScalar, typename ResScalar, typename ResPacket, typename DataMapper>
|
||||
struct RhsLoopStruct<Architecture, CPU, Index, LhsScalar, LhsPackMap, RhsScalar, RhsPackMap, AccScalar, ResScalar, ResPacket, DataMapper, -1>
|
||||
{
|
||||
EIGEN_STRONG_INLINE void operator()(Index colIdx, const DataMapper&,
|
||||
Index, Index, Index, ResScalar, const ResPacket&, LhsPackMap&, RhsPackMap&) {}
|
||||
};
|
||||
|
||||
template<int Architecture, int CPU, typename ResScalar, typename AccScalar, typename LhsScalar, typename RhsScalar, typename Index, typename DataMapper>
|
||||
EIGEN_STRONG_INLINE void gemm(const DataMapper& res, const LhsScalar* blockA, const RhsScalar* blockB,
|
||||
Index rows, Index depth, Index cols, ResScalar alpha, Index strideA, Index strideB, Index offsetA, Index offsetB)
|
||||
{
|
||||
using ResPacket = typename unpacket_traits<ResScalar>::type;
|
||||
typedef PackMap<Architecture, CPU, Index, LhsScalar, DataMapper, true> LhsPackMap;
|
||||
typedef PackMap<Architecture, CPU, Index, RhsScalar, DataMapper, false> RhsPackMap;
|
||||
|
||||
#ifdef __DEBUG__
|
||||
std::cout << "blockA" << std::endl;
|
||||
for(auto i = 0; i < rows*depth; i++)
|
||||
{
|
||||
if(i % 4 == 0 && i > 0)
|
||||
std::cout << std::endl;
|
||||
std::cout << blockA[i] << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
std::cout << "blockB" << std::endl;
|
||||
for(auto i = 0; i < depth*cols; i++)
|
||||
{
|
||||
if(i % 4 == 0 && i > 0)
|
||||
std::cout << std::endl;
|
||||
std::cout << blockB[i] << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
#endif
|
||||
asm __volatile__("#BEGING_GEBP\n\t");
|
||||
RhsLoopStruct<Architecture, CPU, Index, LhsScalar, LhsPackMap, RhsScalar, RhsPackMap, AccScalar, ResScalar, ResPacket, DataMapper, SHAPES_COUNT<0, 0, LhsScalar, RhsScalar>-1> rhsLS;
|
||||
LhsPackMap lhsPackMap(blockA, depth, strideA, offsetA);
|
||||
RhsPackMap rhsPackMap(blockB, depth, strideB, offsetB);
|
||||
|
||||
ResPacket pAlpha = pset1<ResPacket>(alpha);
|
||||
|
||||
rhsLS(0, res, rows, depth, cols, alpha, pAlpha, lhsPackMap, rhsPackMap);
|
||||
asm __volatile__("#END_GEBP\n\t");
|
||||
}
|
||||
/*
|
||||
template<typename Index, typename DataMapper, int nr, bool Conjugate, bool PanelMode>
|
||||
struct gemm_pack_rhs<float, Index, DataMapper, nr, ColMajor, Conjugate, PanelMode>
|
||||
{
|
||||
void operator()(float* blockB, const DataMapper& rhs, Index depth, Index cols, Index stride=0, Index offset=0);
|
||||
};
|
||||
|
||||
template<typename Index, typename DataMapper, int nr, bool Conjugate, bool PanelMode>
|
||||
void gemm_pack_rhs<float, Index, DataMapper, nr, ColMajor, Conjugate, PanelMode>
|
||||
::operator()(float* blockB, const DataMapper& rhs, Index depth, Index cols, Index stride, Index offset)
|
||||
{
|
||||
rhs_pack<0, 0, Index, float, DataMapper, Conjugate, PanelMode, ColMajor> pack;
|
||||
pack(blockB, rhs, depth, cols, stride, offset);
|
||||
}
|
||||
|
||||
template<typename Index, typename DataMapper, int nr, bool Conjugate, bool PanelMode>
|
||||
struct gemm_pack_rhs<float, Index, DataMapper, nr, RowMajor, Conjugate, PanelMode>
|
||||
{
|
||||
void operator()(float* blockB, const DataMapper& rhs, Index depth, Index cols, Index stride=0, Index offset=0);
|
||||
};
|
||||
|
||||
template<typename Index, typename DataMapper, int nr, bool Conjugate, bool PanelMode>
|
||||
void gemm_pack_rhs<float, Index, DataMapper, nr, RowMajor, Conjugate, PanelMode>
|
||||
::operator()(float* blockB, const DataMapper& rhs, Index depth, Index cols, Index stride, Index offset)
|
||||
{
|
||||
rhs_pack<0, 0, Index, float, DataMapper, Conjugate, PanelMode, RowMajor> pack;
|
||||
pack(blockB, rhs, depth, cols, stride, offset);
|
||||
}
|
||||
|
||||
template<typename Index, typename DataMapper, int Pack1, int Pack2, typename Packet, bool Conjugate, bool PanelMode>
|
||||
struct gemm_pack_lhs<float, Index, DataMapper, Pack1, Pack2, Packet, RowMajor, Conjugate, PanelMode>
|
||||
{
|
||||
void operator()(float* blockA, const DataMapper& lhs, Index depth, Index rows, Index stride=0, Index offset=0);
|
||||
};
|
||||
|
||||
template<typename Index, typename DataMapper, int Pack1, int Pack2, typename Packet, bool Conjugate, bool PanelMode>
|
||||
void gemm_pack_lhs<float, Index, DataMapper, Pack1, Pack2, Packet, RowMajor, Conjugate, PanelMode>
|
||||
::operator()(float* blockA, const DataMapper& lhs, Index depth, Index rows, Index stride, Index offset)
|
||||
{
|
||||
lhs_pack<0, 0, Index, float, DataMapper, Conjugate, PanelMode, RowMajor> pack;
|
||||
pack(blockA, lhs, depth, rows, stride, offset);
|
||||
}
|
||||
|
||||
template<typename Index, typename DataMapper, int Pack1, int Pack2, typename Packet, bool Conjugate, bool PanelMode>
|
||||
struct gemm_pack_lhs<float, Index, DataMapper, Pack1, Pack2, Packet, ColMajor, Conjugate, PanelMode>
|
||||
{
|
||||
void operator()(float* blockA, const DataMapper& lhs, Index depth, Index rows, Index stride=0, Index offset=0);
|
||||
};
|
||||
|
||||
template<typename Index, typename DataMapper, int Pack1, int Pack2, typename Packet, bool Conjugate, bool PanelMode>
|
||||
void gemm_pack_lhs<float, Index, DataMapper, Pack1, Pack2, Packet, ColMajor, Conjugate, PanelMode>
|
||||
::operator()(float* blockA, const DataMapper& lhs, Index depth, Index rows, Index stride, Index offset)
|
||||
{
|
||||
lhs_pack<0, 0, Index, float, DataMapper, Conjugate, PanelMode, ColMajor> pack;
|
||||
pack(blockA, lhs, depth, rows, stride, offset);
|
||||
}
|
||||
*/
|
||||
template<typename Index, typename DataMapper, int mr, int nr, bool ConjugateLhs, bool ConjugateRhs>
|
||||
struct gebp_kernel<float, float, Index, DataMapper, mr, nr, ConjugateLhs, ConjugateRhs>
|
||||
{
|
||||
void operator()(const DataMapper& res, const float* blockA, const float* blockB,
|
||||
Index rows, Index depth, Index cols, float alpha,
|
||||
Index strideA=-1, Index strideB=-1, Index offsetA=0, Index offsetB=0);
|
||||
};
|
||||
|
||||
template<typename Index, typename DataMapper, int mr, int nr, bool ConjugateLhs, bool ConjugateRhs>
|
||||
void gebp_kernel<float, float, Index, DataMapper, mr, nr, ConjugateLhs, ConjugateRhs>
|
||||
::operator()(const DataMapper& res, const float* blockA, const float* blockB,
|
||||
Index rows, Index depth, Index cols, float alpha,
|
||||
Index strideA, Index strideB, Index offsetA, Index offsetB)
|
||||
{
|
||||
gemm<0, 0, float, float, float, float, Index, DataMapper>(res, blockA, blockB, rows, depth, cols, alpha, strideA, strideB, offsetA, offsetB);
|
||||
}
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
#endif // EIGEN_MATRIX_PRODUCT_NEON_H
|
||||
@@ -194,13 +194,16 @@ struct packet_traits<float> : default_packet_traits
|
||||
HasBlend = 0,
|
||||
|
||||
HasDiv = 1,
|
||||
HasFloor = 0,
|
||||
HasFloor = 1,
|
||||
HasCeil = 1,
|
||||
HasRint = 1,
|
||||
|
||||
HasSin = EIGEN_FAST_MATH,
|
||||
HasCos = EIGEN_FAST_MATH,
|
||||
HasLog = 1,
|
||||
HasExp = 1,
|
||||
HasSqrt = 1,
|
||||
HasRsqrt = 1,
|
||||
HasTanh = EIGEN_FAST_MATH,
|
||||
HasErf = EIGEN_FAST_MATH,
|
||||
HasBessel = 0, // Issues with accuracy.
|
||||
@@ -1462,32 +1465,6 @@ template<> EIGEN_STRONG_INLINE Packet2f pcmp_lt_or_nan<Packet2f>(const Packet2f&
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pcmp_lt_or_nan<Packet4f>(const Packet4f& a, const Packet4f& b)
|
||||
{ return vreinterpretq_f32_u32(vmvnq_u32(vcgeq_f32(a,b))); }
|
||||
|
||||
// WARNING: this pfloor implementation makes sense for inputs that fit in
|
||||
// signed int32 integers (up to ~2.14e9), hence this is currently only used
|
||||
// by pexp and not exposed through HasFloor.
|
||||
template<> EIGEN_STRONG_INLINE Packet2f pfloor<Packet2f>(const Packet2f& a)
|
||||
{
|
||||
const Packet2f cst_1 = pset1<Packet2f>(1.0f);
|
||||
/* perform a floorf */
|
||||
Packet2f tmp = vcvt_f32_s32(vcvt_s32_f32(a));
|
||||
|
||||
/* if greater, substract 1 */
|
||||
Packet2ui mask = vcgt_f32(tmp, a);
|
||||
mask = vand_u32(mask, vreinterpret_u32_f32(cst_1));
|
||||
return vsub_f32(tmp, vreinterpret_f32_u32(mask));
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pfloor<Packet4f>(const Packet4f& a)
|
||||
{
|
||||
const Packet4f cst_1 = pset1<Packet4f>(1.0f);
|
||||
/* perform a floorf */
|
||||
Packet4f tmp = vcvtq_f32_s32(vcvtq_s32_f32(a));
|
||||
|
||||
/* if greater, substract 1 */
|
||||
Packet4ui mask = vcgtq_f32(tmp, a);
|
||||
mask = vandq_u32(mask, vreinterpretq_u32_f32(cst_1));
|
||||
return vsubq_f32(tmp, vreinterpretq_f32_u32(mask));
|
||||
}
|
||||
|
||||
// Logical Operations are not supported for float, so we have to reinterpret casts using NEON intrinsics
|
||||
template<> EIGEN_STRONG_INLINE Packet2f pand<Packet2f>(const Packet2f& a, const Packet2f& b)
|
||||
{ return vreinterpret_f32_u32(vand_u32(vreinterpret_u32_f32(a),vreinterpret_u32_f32(b))); }
|
||||
@@ -3206,6 +3183,98 @@ template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet2l pselect(const Packet2l
|
||||
template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet2ul pselect(const Packet2ul& mask, const Packet2ul& a, const Packet2ul& b)
|
||||
{ return vbslq_u64(mask, a, b); }
|
||||
|
||||
// Use armv8 rounding intinsics if available.
|
||||
#if EIGEN_ARCH_ARMV8
|
||||
template<> EIGEN_STRONG_INLINE Packet2f print<Packet2f>(const Packet2f& a)
|
||||
{ return vrndn_f32(a); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f print<Packet4f>(const Packet4f& a)
|
||||
{ return vrndnq_f32(a); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2f pfloor<Packet2f>(const Packet2f& a)
|
||||
{ return vrndm_f32(a); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pfloor<Packet4f>(const Packet4f& a)
|
||||
{ return vrndmq_f32(a); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2f pceil<Packet2f>(const Packet2f& a)
|
||||
{ return vrndp_f32(a); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pceil<Packet4f>(const Packet4f& a)
|
||||
{ return vrndpq_f32(a); }
|
||||
|
||||
#else
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f print(const Packet4f& a) {
|
||||
// Adds and subtracts signum(a) * 2^23 to force rounding.
|
||||
const Packet4f limit = pset1<Packet4f>(static_cast<float>(1<<23));
|
||||
const Packet4f abs_a = pabs(a);
|
||||
Packet4f r = padd(abs_a, limit);
|
||||
// Don't compile-away addition and subtraction.
|
||||
EIGEN_OPTIMIZATION_BARRIER(r);
|
||||
r = psub(r, limit);
|
||||
// If greater than limit, simply return a. Otherwise, account for sign.
|
||||
r = pselect(pcmp_lt(abs_a, limit),
|
||||
pselect(pcmp_lt(a, pzero(a)), pnegate(r), r), a);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2f print(const Packet2f& a) {
|
||||
// Adds and subtracts signum(a) * 2^23 to force rounding.
|
||||
const Packet2f limit = pset1<Packet2f>(static_cast<float>(1<<23));
|
||||
const Packet2f abs_a = pabs(a);
|
||||
Packet2f r = padd(abs_a, limit);
|
||||
// Don't compile-away addition and subtraction.
|
||||
EIGEN_OPTIMIZATION_BARRIER(r);
|
||||
r = psub(r, limit);
|
||||
// If greater than limit, simply return a. Otherwise, account for sign.
|
||||
r = pselect(pcmp_lt(abs_a, limit),
|
||||
pselect(pcmp_lt(a, pzero(a)), pnegate(r), r), a);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pfloor<Packet4f>(const Packet4f& a)
|
||||
{
|
||||
const Packet4f cst_1 = pset1<Packet4f>(1.0f);
|
||||
Packet4f tmp = print<Packet4f>(a);
|
||||
// If greater, subtract one.
|
||||
Packet4f mask = pcmp_lt(a, tmp);
|
||||
mask = pand(mask, cst_1);
|
||||
return psub(tmp, mask);
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2f pfloor<Packet2f>(const Packet2f& a)
|
||||
{
|
||||
const Packet2f cst_1 = pset1<Packet2f>(1.0f);
|
||||
Packet2f tmp = print<Packet2f>(a);
|
||||
// If greater, subtract one.
|
||||
Packet2f mask = pcmp_lt(a, tmp);
|
||||
mask = pand(mask, cst_1);
|
||||
return psub(tmp, mask);
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pceil<Packet4f>(const Packet4f& a)
|
||||
{
|
||||
const Packet4f cst_1 = pset1<Packet4f>(1.0f);
|
||||
Packet4f tmp = print<Packet4f>(a);
|
||||
// If smaller, add one.
|
||||
Packet4f mask = pcmp_lt(tmp, a);
|
||||
mask = pand(mask, cst_1);
|
||||
return padd(tmp, mask);
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2f pceil<Packet2f>(const Packet2f& a)
|
||||
{
|
||||
const Packet2f cst_1 = pset1<Packet2f>(1.0);
|
||||
Packet2f tmp = print<Packet2f>(a);
|
||||
// If smaller, add one.
|
||||
Packet2f mask = pcmp_lt(tmp, a);
|
||||
mask = pand(mask, cst_1);
|
||||
return padd(tmp, mask);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Computes the integer square root
|
||||
* @remarks The calculation is performed using an algorithm which iterates through each binary digit of the result
|
||||
@@ -3297,41 +3366,41 @@ template<> EIGEN_STRONG_INLINE Packet4ui psqrt(const Packet4ui& a) {
|
||||
return res;
|
||||
}
|
||||
|
||||
#if EIGEN_FAST_MATH
|
||||
|
||||
/* Functions for sqrt support packet2f/packet4f.*/
|
||||
// The EIGEN_FAST_MATH version uses the vrsqrte_f32 approximation and one step
|
||||
// of Newton's method, at a cost of 1-2 bits of precision as opposed to the
|
||||
// exact solution. It does not handle +inf, or denormalized numbers correctly.
|
||||
// The main advantage of this approach is not just speed, but also the fact that
|
||||
// it can be inlined and pipelined with other computations, further reducing its
|
||||
// effective latency. This is similar to Quake3's fast inverse square root.
|
||||
// For more details see: http://www.beyond3d.com/content/articles/8/
|
||||
template<> EIGEN_STRONG_INLINE Packet4f psqrt(const Packet4f& _x){
|
||||
Packet4ui denormal_mask = vandq_u32(vcgeq_f32(_x, vdupq_n_f32(0.0f)),
|
||||
vcltq_f32(_x, pset1<Packet4f>((std::numeric_limits<float>::min)())));
|
||||
template<> EIGEN_STRONG_INLINE Packet4f prsqrt(const Packet4f& a) {
|
||||
// Compute approximate reciprocal sqrt.
|
||||
Packet4f x = vrsqrteq_f32(_x);
|
||||
// Do one Newton's iteration for 1/sqrt(x).
|
||||
x = vmulq_f32(vrsqrtsq_f32(vmulq_f32(_x, x), x), x);
|
||||
// Flush results for denormals to zero.
|
||||
return vreinterpretq_f32_u32(vbicq_u32(vreinterpretq_u32_f32(pmul(_x, x)), denormal_mask));
|
||||
Packet4f x = vrsqrteq_f32(a);
|
||||
// Do Newton iterations for 1/sqrt(x).
|
||||
x = vmulq_f32(vrsqrtsq_f32(vmulq_f32(a, x), x), x);
|
||||
x = vmulq_f32(vrsqrtsq_f32(vmulq_f32(a, x), x), x);
|
||||
const Packet4f infinity = pset1<Packet4f>(NumTraits<float>::infinity());
|
||||
return pselect(pcmp_eq(a, pzero(a)), infinity, x);
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2f psqrt(const Packet2f& _x) {
|
||||
Packet2ui denormal_mask = vand_u32(vcge_f32(_x, vdup_n_f32(0.0f)),
|
||||
vclt_f32(_x, pset1<Packet2f>((std::numeric_limits<float>::min)())));
|
||||
template<> EIGEN_STRONG_INLINE Packet2f prsqrt(const Packet2f& a) {
|
||||
// Compute approximate reciprocal sqrt.
|
||||
Packet2f x = vrsqrte_f32(_x);
|
||||
// Do one Newton's iteration for 1/sqrt(x).
|
||||
x = vmul_f32(vrsqrts_f32(vmul_f32(_x, x), x), x);
|
||||
// Flush results for denormals to zero.
|
||||
return vreinterpret_f32_u32(vbic_u32(vreinterpret_u32_f32(pmul(_x, x)), denormal_mask));
|
||||
Packet2f x = vrsqrte_f32(a);
|
||||
// Do Newton iterations for 1/sqrt(x).
|
||||
x = vmul_f32(vrsqrts_f32(vmul_f32(a, x), x), x);
|
||||
x = vmul_f32(vrsqrts_f32(vmul_f32(a, x), x), x);
|
||||
const Packet2f infinity = pset1<Packet2f>(NumTraits<float>::infinity());
|
||||
return pselect(pcmp_eq(a, pzero(a)), infinity, x);
|
||||
}
|
||||
|
||||
#else
|
||||
// Unfortunately vsqrt_f32 is only available for A64.
|
||||
#if EIGEN_ARCH_ARM64
|
||||
template<> EIGEN_STRONG_INLINE Packet4f psqrt(const Packet4f& _x){return vsqrtq_f32(_x);}
|
||||
template<> EIGEN_STRONG_INLINE Packet2f psqrt(const Packet2f& _x){return vsqrt_f32(_x); }
|
||||
#else
|
||||
template<> EIGEN_STRONG_INLINE Packet4f psqrt(const Packet4f& a) {
|
||||
const Packet4f infinity = pset1<Packet4f>(NumTraits<float>::infinity());
|
||||
const Packet4f is_zero_or_inf = por(pcmp_eq(a, pzero(a)), pcmp_eq(a, infinity));
|
||||
return pselect(is_zero_or_inf, a, pmul(a, prsqrt(a)));
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE Packet2f psqrt(const Packet2f& a) {
|
||||
const Packet2f infinity = pset1<Packet2f>(NumTraits<float>::infinity());
|
||||
const Packet2f is_zero_or_inf = por(pcmp_eq(a, pzero(a)), pcmp_eq(a, infinity));
|
||||
return pselect(is_zero_or_inf, a, pmul(a, prsqrt(a)));
|
||||
}
|
||||
#endif
|
||||
|
||||
//---------- bfloat16 ----------
|
||||
@@ -3370,6 +3439,8 @@ template<> struct packet_traits<bfloat16> : default_packet_traits
|
||||
HasBlend = 0,
|
||||
HasDiv = 1,
|
||||
HasFloor = 1,
|
||||
HasCeil = 1,
|
||||
HasRint = 1,
|
||||
|
||||
HasSin = EIGEN_FAST_MATH,
|
||||
HasCos = EIGEN_FAST_MATH,
|
||||
@@ -3531,11 +3602,21 @@ template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4bf pselect(const Packet4
|
||||
return pselect<Packet4us>(mask, a, b);
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4bf print<Packet4bf>(const Packet4bf& a)
|
||||
{
|
||||
return F32ToBf16(print<Packet4f>(Bf16ToF32(a)));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4bf pfloor<Packet4bf>(const Packet4bf& a)
|
||||
{
|
||||
return F32ToBf16(pfloor<Packet4f>(Bf16ToF32(a)));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4bf pceil<Packet4bf>(const Packet4bf& a)
|
||||
{
|
||||
return F32ToBf16(pceil<Packet4f>(Bf16ToF32(a)));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4bf pconj(const Packet4bf& a) { return a; }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4bf padd<Packet4bf>(const Packet4bf& a, const Packet4bf& b) {
|
||||
@@ -3710,13 +3791,16 @@ template<> struct packet_traits<double> : default_packet_traits
|
||||
HasBlend = 0,
|
||||
|
||||
HasDiv = 1,
|
||||
HasFloor = 0,
|
||||
HasFloor = 1,
|
||||
HasCeil = 1,
|
||||
HasRint = 1,
|
||||
|
||||
HasSin = 0,
|
||||
HasCos = 0,
|
||||
HasLog = 1,
|
||||
HasExp = 1,
|
||||
HasSqrt = 1,
|
||||
HasRsqrt = 1,
|
||||
HasTanh = 0,
|
||||
HasErf = 0
|
||||
};
|
||||
@@ -3788,21 +3872,6 @@ template<> EIGEN_STRONG_INLINE Packet2d pmax<Packet2d>(const Packet2d& a, const
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pmax<PropagateNaN, Packet2d>(const Packet2d& a, const Packet2d& b) { return pmax<Packet2d>(a, b); }
|
||||
|
||||
// WARNING: this pfloor implementation makes sense for inputs that fit in
|
||||
// signed int64 integers (up to ~9.22e18), hence this is currently only used
|
||||
// by pexp and not exposed through HasFloor.
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pfloor<Packet2d>(const Packet2d& a)
|
||||
{
|
||||
const Packet2d cst_1 = pset1<Packet2d>(1.0);
|
||||
/* perform a floorf */
|
||||
const Packet2d tmp = vcvtq_f64_s64(vcvtq_s64_f64(a));
|
||||
|
||||
/* if greater, substract 1 */
|
||||
uint64x2_t mask = vcgtq_f64(tmp, a);
|
||||
mask = vandq_u64(mask, vreinterpretq_u64_f64(cst_1));
|
||||
return vsubq_f64(tmp, vreinterpretq_f64_u64(mask));
|
||||
}
|
||||
|
||||
// Logical Operations are not supported for float, so we have to reinterpret casts using NEON intrinsics
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pand<Packet2d>(const Packet2d& a, const Packet2d& b)
|
||||
{ return vreinterpretq_f64_u64(vandq_u64(vreinterpretq_u64_f64(a),vreinterpretq_u64_f64(b))); }
|
||||
@@ -3906,6 +3975,15 @@ ptranspose(PacketBlock<Packet2d, 2>& kernel)
|
||||
template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet2d pselect( const Packet2d& mask, const Packet2d& a, const Packet2d& b)
|
||||
{ return vbslq_f64(vreinterpretq_u64_f64(mask), a, b); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2d print<Packet2d>(const Packet2d& a)
|
||||
{ return vrndnq_f64(a); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pfloor<Packet2d>(const Packet2d& a)
|
||||
{ return vrndmq_f64(a); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pceil<Packet2d>(const Packet2d& a)
|
||||
{ return vrndpq_f64(a); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pldexp<Packet2d>(const Packet2d& a, const Packet2d& exponent)
|
||||
{ return pldexp_generic(a, exponent); }
|
||||
|
||||
@@ -3915,6 +3993,17 @@ template<> EIGEN_STRONG_INLINE Packet2d pfrexp<Packet2d>(const Packet2d& a, Pack
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pset1frombits<Packet2d>(uint64_t from)
|
||||
{ return vreinterpretq_f64_u64(vdupq_n_u64(from)); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2d prsqrt(const Packet2d& a) {
|
||||
// Compute approximate reciprocal sqrt.
|
||||
Packet2d x = vrsqrteq_f64(a);
|
||||
// Do Newton iterations for 1/sqrt(x).
|
||||
x = vmulq_f64(vrsqrtsq_f64(vmulq_f64(a, x), x), x);
|
||||
x = vmulq_f64(vrsqrtsq_f64(vmulq_f64(a, x), x), x);
|
||||
x = vmulq_f64(vrsqrtsq_f64(vmulq_f64(a, x), x), x);
|
||||
const Packet2d infinity = pset1<Packet2d>(NumTraits<double>::infinity());
|
||||
return pselect(pcmp_eq(a, pzero(a)), infinity, x);
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2d psqrt(const Packet2d& _x){ return vsqrtq_f64(_x); }
|
||||
|
||||
#endif // EIGEN_ARCH_ARM64
|
||||
@@ -3954,14 +4043,17 @@ struct packet_traits<Eigen::half> : default_packet_traits {
|
||||
HasReduxp = 1,
|
||||
HasDiv = 1,
|
||||
HasFloor = 1,
|
||||
HasCeil = 1,
|
||||
HasRint = 1,
|
||||
HasSin = 0,
|
||||
HasCos = 0,
|
||||
HasLog = 0,
|
||||
HasExp = 0,
|
||||
HasSqrt = 1,
|
||||
HasRsqrt = 1,
|
||||
HasErf = EIGEN_FAST_MATH,
|
||||
HasBessel = 0, // Issues with accuracy.
|
||||
HasNdtri = 0,
|
||||
HasNdtri = 0
|
||||
};
|
||||
};
|
||||
|
||||
@@ -4164,28 +4256,28 @@ EIGEN_STRONG_INLINE Packet4hf pcmp_lt_or_nan<Packet4hf>(const Packet4hf& a, cons
|
||||
}
|
||||
|
||||
template <>
|
||||
EIGEN_STRONG_INLINE Packet8hf pfloor<Packet8hf>(const Packet8hf& a) {
|
||||
const Packet8hf cst_1 = pset1<Packet8hf>(Eigen::half(1.0f));
|
||||
/* perform a floorf */
|
||||
Packet8hf tmp = vcvtq_f16_s16(vcvtq_s16_f16(a));
|
||||
|
||||
/* if greater, substract 1 */
|
||||
uint16x8_t mask = vcgtq_f16(tmp, a);
|
||||
mask = vandq_u16(mask, vreinterpretq_u16_f16(cst_1));
|
||||
return vsubq_f16(tmp, vreinterpretq_f16_u16(mask));
|
||||
}
|
||||
EIGEN_STRONG_INLINE Packet8hf print<Packet8hf>(const Packet8hf& a)
|
||||
{ return vrndnq_f16(a); }
|
||||
|
||||
template <>
|
||||
EIGEN_STRONG_INLINE Packet4hf pfloor<Packet4hf>(const Packet4hf& a) {
|
||||
const Packet4hf cst_1 = pset1<Packet4hf>(Eigen::half(1.0f));
|
||||
/* perform a floorf */
|
||||
Packet4hf tmp = vcvt_f16_s16(vcvt_s16_f16(a));
|
||||
EIGEN_STRONG_INLINE Packet4hf print<Packet4hf>(const Packet4hf& a)
|
||||
{ return vrndn_f16(a); }
|
||||
|
||||
/* if greater, substract 1 */
|
||||
uint16x4_t mask = vcgt_f16(tmp, a);
|
||||
mask = vand_u16(mask, vreinterpret_u16_f16(cst_1));
|
||||
return vsub_f16(tmp, vreinterpret_f16_u16(mask));
|
||||
}
|
||||
template <>
|
||||
EIGEN_STRONG_INLINE Packet8hf pfloor<Packet8hf>(const Packet8hf& a)
|
||||
{ return vrndmq_f16(a); }
|
||||
|
||||
template <>
|
||||
EIGEN_STRONG_INLINE Packet4hf pfloor<Packet4hf>(const Packet4hf& a)
|
||||
{ return vrndm_f16(a); }
|
||||
|
||||
template <>
|
||||
EIGEN_STRONG_INLINE Packet8hf pceil<Packet8hf>(const Packet8hf& a)
|
||||
{ return vrndpq_f16(a); }
|
||||
|
||||
template <>
|
||||
EIGEN_STRONG_INLINE Packet4hf pceil<Packet4hf>(const Packet4hf& a)
|
||||
{ return vrndp_f16(a); }
|
||||
|
||||
template <>
|
||||
EIGEN_STRONG_INLINE Packet8hf psqrt<Packet8hf>(const Packet8hf& a) {
|
||||
|
||||
192
Eigen/src/Core/arch/NEON/PackingOps.h
Normal file
192
Eigen/src/Core/arch/NEON/PackingOps.h
Normal file
@@ -0,0 +1,192 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2021 Everton Constantino (everton.constantino@hotmail.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_PACKING_OPS_NEON_H
|
||||
#define EIGEN_PACKING_OPS_NEON_H
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
#ifdef __ENABLE_CUSTOM_PACKING__
|
||||
|
||||
template<int CPU, typename Scalar, bool isLhs>
|
||||
constexpr int PACK_SHAPES_COUNT<0, CPU, Scalar, isLhs> = 3;
|
||||
|
||||
template<int CPU, typename Scalar>
|
||||
constexpr int PACK_SHAPES_COUNT<0, CPU, Scalar, true> = 4;
|
||||
|
||||
template<int CPU, typename Scalar, bool isLhs>
|
||||
constexpr int PACK_SHAPES<0, CPU, Scalar, isLhs>[PACK_SHAPES_COUNT<0, CPU, Scalar, isLhs>][PACK_SHAPES_DIMENSION] = {{1,1,PACK_SHAPES_END},{4,1,0},{4,4,0}};
|
||||
|
||||
template<int CPU, typename Scalar>
|
||||
constexpr int PACK_SHAPES<0, CPU, Scalar, true>[PACK_SHAPES_COUNT<0, CPU, Scalar, true>][PACK_SHAPES_DIMENSION] = {{1,1,PACK_SHAPES_END},{4,1,0},{4,4,0},{8,1,2}};
|
||||
|
||||
template<int CPU, typename Index, typename Scalar, bool isLhs, typename DataMapper, bool Conjugate, bool PanelMode, int StorageOrder>
|
||||
struct PackingOperator<0, CPU, Index, Scalar, isLhs, DataMapper, Conjugate, PanelMode, StorageOrder, 4, 4>
|
||||
{
|
||||
EIGEN_STRONG_INLINE Scalar* operator()(Index d1Idx, Index d2Idx, Scalar *block, const DataMapper& data)
|
||||
{
|
||||
using Packet = typename packet_traits<Scalar>::type;
|
||||
constexpr int vectorSize = packet_traits<Scalar>::size;
|
||||
|
||||
Scalar *c = block;
|
||||
|
||||
if(!isLhs)
|
||||
{
|
||||
int tD = d1Idx;
|
||||
d1Idx = d2Idx;
|
||||
d2Idx = tD;
|
||||
}
|
||||
|
||||
if(isLhs && StorageOrder == ColMajor || !isLhs && StorageOrder == RowMajor)
|
||||
{
|
||||
Packet p0 = data.template loadPacket<Packet>(d1Idx, d2Idx + 0);
|
||||
Packet p1 = data.template loadPacket<Packet>(d1Idx, d2Idx + 1);
|
||||
Packet p2 = data.template loadPacket<Packet>(d1Idx, d2Idx + 2);
|
||||
Packet p3 = data.template loadPacket<Packet>(d1Idx, d2Idx + 3);
|
||||
|
||||
pstore<Scalar>(c + 0*vectorSize, p0);
|
||||
pstore<Scalar>(c + 1*vectorSize, p1);
|
||||
pstore<Scalar>(c + 2*vectorSize, p2);
|
||||
pstore<Scalar>(c + 3*vectorSize, p3);
|
||||
c+=4*vectorSize;
|
||||
} else {
|
||||
PacketBlock<Packet, 4> pblock;
|
||||
|
||||
pblock.packet[0] = data.template loadPacket<Packet>(d1Idx, d2Idx + 0);
|
||||
pblock.packet[1] = data.template loadPacket<Packet>(d1Idx, d2Idx + 1);
|
||||
pblock.packet[2] = data.template loadPacket<Packet>(d1Idx, d2Idx + 2);
|
||||
pblock.packet[3] = data.template loadPacket<Packet>(d1Idx, d2Idx + 3);
|
||||
|
||||
ptranspose(pblock);
|
||||
|
||||
pstore<Scalar>(c + 0*vectorSize, pblock.packet[0]);
|
||||
pstore<Scalar>(c + 1*vectorSize, pblock.packet[1]);
|
||||
pstore<Scalar>(c + 2*vectorSize, pblock.packet[2]);
|
||||
pstore<Scalar>(c + 3*vectorSize, pblock.packet[3]);
|
||||
c+=4*vectorSize;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
template<int CPU, typename Index, typename Scalar, bool isLhs, typename DataMapper, bool Conjugate, bool PanelMode, int StorageOrder>
|
||||
struct PackingOperator<0, CPU, Index, Scalar, isLhs, DataMapper, Conjugate, PanelMode, StorageOrder, 8, 1>
|
||||
{
|
||||
EIGEN_STRONG_INLINE Scalar* operator()(Index d1Idx, Index d2Idx, Scalar *block, const DataMapper& data)
|
||||
{
|
||||
using Packet = typename packet_traits<Scalar>::type;
|
||||
Scalar *c = block;
|
||||
if(isLhs && StorageOrder == ColMajor)
|
||||
{
|
||||
Packet p = data.template loadPacket<Packet>(d1Idx + 0, d2Idx);
|
||||
pstore<Scalar>(c, p);
|
||||
c+=4;
|
||||
p = data.template loadPacket<Packet>(d1Idx + 4, d2Idx);
|
||||
pstore<Scalar>(c, p);
|
||||
c+=4;
|
||||
} else if(!isLhs && StorageOrder == RowMajor) {
|
||||
Packet p = data.template loadPacket<Packet>(d2Idx, d1Idx + 0);
|
||||
pstore<Scalar>(c, p);
|
||||
c+=4;
|
||||
p = data.template loadPacket<Packet>(d2Idx, d1Idx + 4);
|
||||
pstore<Scalar>(c, p);
|
||||
c+=4;
|
||||
} else {
|
||||
if(isLhs)
|
||||
{
|
||||
*c = data(d1Idx + 0, d2Idx + 0);
|
||||
c++;
|
||||
*c = data(d1Idx + 1, d2Idx + 0);
|
||||
c++;
|
||||
*c = data(d1Idx + 2, d2Idx + 0);
|
||||
c++;
|
||||
*c = data(d1Idx + 3, d2Idx + 0);
|
||||
c++;
|
||||
*c = data(d1Idx + 0, d2Idx + 4);
|
||||
c++;
|
||||
*c = data(d1Idx + 1, d2Idx + 4);
|
||||
c++;
|
||||
*c = data(d1Idx + 2, d2Idx + 4);
|
||||
c++;
|
||||
*c = data(d1Idx + 3, d2Idx + 4);
|
||||
c++;
|
||||
} else {
|
||||
*c = data(d2Idx, d1Idx + 0);
|
||||
c++;
|
||||
*c = data(d2Idx, d1Idx + 1);
|
||||
c++;
|
||||
*c = data(d2Idx, d1Idx + 2);
|
||||
c++;
|
||||
*c = data(d2Idx, d1Idx + 3);
|
||||
c++;
|
||||
*c = data(d2Idx + 4, d1Idx + 0);
|
||||
c++;
|
||||
*c = data(d2Idx + 4, d1Idx + 1);
|
||||
c++;
|
||||
*c = data(d2Idx + 4, d1Idx + 2);
|
||||
c++;
|
||||
*c = data(d2Idx + 4, d1Idx + 3);
|
||||
c++;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
template<int CPU, typename Index, typename Scalar, bool isLhs, typename DataMapper, bool Conjugate, bool PanelMode, int StorageOrder>
|
||||
struct PackingOperator<0, CPU, Index, Scalar, isLhs, DataMapper, Conjugate, PanelMode, StorageOrder, 4, 1>
|
||||
{
|
||||
EIGEN_STRONG_INLINE Scalar* operator()(Index d1Idx, Index d2Idx, Scalar *block, const DataMapper& data)
|
||||
{
|
||||
using Packet = typename packet_traits<Scalar>::type;
|
||||
Scalar *c = block;
|
||||
if(isLhs && StorageOrder == ColMajor)
|
||||
{
|
||||
Packet p = data.template loadPacket<Packet>(d1Idx, d2Idx);
|
||||
pstore<Scalar>(c, p);
|
||||
c+=4;
|
||||
} else if(!isLhs && StorageOrder == RowMajor) {
|
||||
Packet p = data.template loadPacket<Packet>(d2Idx, d1Idx);
|
||||
pstore<Scalar>(c, p);
|
||||
c+=4;
|
||||
} else {
|
||||
if(isLhs)
|
||||
{
|
||||
*c = data(d1Idx + 0, d2Idx);
|
||||
c++;
|
||||
*c = data(d1Idx + 1, d2Idx);
|
||||
c++;
|
||||
*c = data(d1Idx + 2, d2Idx);
|
||||
c++;
|
||||
*c = data(d1Idx + 3, d2Idx);
|
||||
c++;
|
||||
} else {
|
||||
*c = data(d2Idx, d1Idx + 0);
|
||||
c++;
|
||||
*c = data(d2Idx, d1Idx + 1);
|
||||
c++;
|
||||
*c = data(d2Idx, d1Idx + 2);
|
||||
c++;
|
||||
*c = data(d2Idx, d1Idx + 3);
|
||||
c++;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __ENABLE_CUSTOM_PACKING__
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_PACKING_OPS_NEON_H
|
||||
@@ -148,13 +148,11 @@ struct packet_traits<float> : default_packet_traits {
|
||||
HasErf = EIGEN_FAST_MATH,
|
||||
HasBlend = 1,
|
||||
HasCeil = 1,
|
||||
HasFloor = 1
|
||||
|
||||
HasFloor = 1,
|
||||
#ifdef EIGEN_VECTORIZE_SSE4_1
|
||||
,
|
||||
HasRint = 1,
|
||||
HasRound = 1
|
||||
HasRound = 1,
|
||||
#endif
|
||||
HasRint = 1
|
||||
};
|
||||
};
|
||||
template <>
|
||||
@@ -175,13 +173,11 @@ struct packet_traits<double> : default_packet_traits {
|
||||
HasRsqrt = 1,
|
||||
HasBlend = 1,
|
||||
HasFloor = 1,
|
||||
HasCeil = 1
|
||||
|
||||
HasCeil = 1,
|
||||
#ifdef EIGEN_VECTORIZE_SSE4_1
|
||||
,
|
||||
HasRound = 1,
|
||||
HasRint = 1
|
||||
#endif
|
||||
HasRint = 1
|
||||
};
|
||||
};
|
||||
#endif
|
||||
@@ -598,9 +594,29 @@ EIGEN_STRONG_INLINE Packet2d pmax<PropagateNaN, Packet2d>(const Packet2d& a, con
|
||||
return pminmax_propagate_nan(a, b, pmax<Packet2d>);
|
||||
}
|
||||
|
||||
template<int N> EIGEN_STRONG_INLINE Packet4i parithmetic_shift_right(Packet4i a) { return _mm_srai_epi32(a,N); }
|
||||
template<int N> EIGEN_STRONG_INLINE Packet4i plogical_shift_right(Packet4i a) { return _mm_srli_epi32(a,N); }
|
||||
template<int N> EIGEN_STRONG_INLINE Packet4i plogical_shift_left(Packet4i a) { return _mm_slli_epi32(a,N); }
|
||||
template<int N> EIGEN_STRONG_INLINE Packet4i parithmetic_shift_right(const Packet4i& a) { return _mm_srai_epi32(a,N); }
|
||||
template<int N> EIGEN_STRONG_INLINE Packet4i plogical_shift_right (const Packet4i& a) { return _mm_srli_epi32(a,N); }
|
||||
template<int N> EIGEN_STRONG_INLINE Packet4i plogical_shift_left (const Packet4i& a) { return _mm_slli_epi32(a,N); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pabs(const Packet4f& a)
|
||||
{
|
||||
const Packet4f mask = _mm_castsi128_ps(_mm_setr_epi32(0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF));
|
||||
return _mm_and_ps(a,mask);
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pabs(const Packet2d& a)
|
||||
{
|
||||
const Packet2d mask = _mm_castsi128_pd(_mm_setr_epi32(0xFFFFFFFF,0x7FFFFFFF,0xFFFFFFFF,0x7FFFFFFF));
|
||||
return _mm_and_pd(a,mask);
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE Packet4i pabs(const Packet4i& a)
|
||||
{
|
||||
#ifdef EIGEN_VECTORIZE_SSSE3
|
||||
return _mm_abs_epi32(a);
|
||||
#else
|
||||
Packet4i aux = _mm_srai_epi32(a,31);
|
||||
return _mm_sub_epi32(_mm_xor_si128(a,aux),aux);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef EIGEN_VECTORIZE_SSE4_1
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pround<Packet4f>(const Packet4f& a)
|
||||
@@ -627,25 +643,49 @@ template<> EIGEN_STRONG_INLINE Packet2d pceil<Packet2d>(const Packet2d& a) { ret
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pfloor<Packet4f>(const Packet4f& a) { return _mm_floor_ps(a); }
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pfloor<Packet2d>(const Packet2d& a) { return _mm_floor_pd(a); }
|
||||
#else
|
||||
template<> EIGEN_STRONG_INLINE Packet4f print(const Packet4f& a) {
|
||||
// Adds and subtracts signum(a) * 2^23 to force rounding.
|
||||
const Packet4f limit = pset1<Packet4f>(static_cast<float>(1<<23));
|
||||
const Packet4f abs_a = pabs(a);
|
||||
Packet4f r = padd(abs_a, limit);
|
||||
// Don't compile-away addition and subtraction.
|
||||
EIGEN_OPTIMIZATION_BARRIER(r);
|
||||
r = psub(r, limit);
|
||||
// If greater than limit, simply return a. Otherwise, account for sign.
|
||||
r = pselect(pcmp_lt(abs_a, limit),
|
||||
pselect(pcmp_lt(a, pzero(a)), pnegate(r), r), a);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2d print(const Packet2d& a) {
|
||||
// Adds and subtracts signum(a) * 2^52 to force rounding.
|
||||
const Packet2d limit = pset1<Packet2d>(static_cast<double>(1ull<<52));
|
||||
const Packet2d abs_a = pabs(a);
|
||||
Packet2d r = padd(abs_a, limit);
|
||||
// Don't compile-away addition and subtraction.
|
||||
EIGEN_OPTIMIZATION_BARRIER(r);
|
||||
r = psub(r, limit);
|
||||
// If greater than limit, simply return a. Otherwise, account for sign.
|
||||
r = pselect(pcmp_lt(abs_a, limit),
|
||||
pselect(pcmp_lt(a, pzero(a)), pnegate(r), r), a);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pfloor<Packet4f>(const Packet4f& a)
|
||||
{
|
||||
const Packet4f cst_1 = pset1<Packet4f>(1.0f);
|
||||
Packet4i emm0 = _mm_cvttps_epi32(a);
|
||||
Packet4f tmp = _mm_cvtepi32_ps(emm0);
|
||||
/* if greater, substract 1 */
|
||||
Packet4f tmp = print<Packet4f>(a);
|
||||
// If greater, subtract one.
|
||||
Packet4f mask = _mm_cmpgt_ps(tmp, a);
|
||||
mask = pand(mask, cst_1);
|
||||
return psub(tmp, mask);
|
||||
}
|
||||
|
||||
// WARNING: this pfloor implementation makes sense for small inputs only,
|
||||
// It is currently only used by pexp and not exposed through HasFloor.
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pfloor<Packet2d>(const Packet2d& a)
|
||||
{
|
||||
const Packet2d cst_1 = pset1<Packet2d>(1.0);
|
||||
Packet4i emm0 = _mm_cvttpd_epi32(a);
|
||||
Packet2d tmp = _mm_cvtepi32_pd(emm0);
|
||||
/* if greater, substract 1 */
|
||||
Packet2d tmp = print<Packet2d>(a);
|
||||
// If greater, subtract one.
|
||||
Packet2d mask = _mm_cmpgt_pd(tmp, a);
|
||||
mask = pand(mask, cst_1);
|
||||
return psub(tmp, mask);
|
||||
@@ -654,22 +694,18 @@ template<> EIGEN_STRONG_INLINE Packet2d pfloor<Packet2d>(const Packet2d& a)
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pceil<Packet4f>(const Packet4f& a)
|
||||
{
|
||||
const Packet4f cst_1 = pset1<Packet4f>(1.0f);
|
||||
Packet4i emm0 = _mm_cvttps_epi32(a);
|
||||
Packet4f tmp = _mm_cvtepi32_ps(emm0);
|
||||
/* if greater, substract 1 */
|
||||
Packet4f tmp = print<Packet4f>(a);
|
||||
// If smaller, add one.
|
||||
Packet4f mask = _mm_cmplt_ps(tmp, a);
|
||||
mask = pand(mask, cst_1);
|
||||
return padd(tmp, mask);
|
||||
}
|
||||
|
||||
// WARNING: this pfloor implementation makes sense for small inputs only,
|
||||
// It is currently only used by pexp and not exposed through HasFloor.
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pceil<Packet2d>(const Packet2d& a)
|
||||
{
|
||||
const Packet2d cst_1 = pset1<Packet2d>(1.0);
|
||||
Packet4i emm0 = _mm_cvttpd_epi32(a);
|
||||
Packet2d tmp = _mm_cvtepi32_pd(emm0);
|
||||
/* if greater, substract 1 */
|
||||
Packet2d tmp = print<Packet2d>(a);
|
||||
// If smaller, add one.
|
||||
Packet2d mask = _mm_cmplt_pd(tmp, a);
|
||||
mask = pand(mask, cst_1);
|
||||
return padd(tmp, mask);
|
||||
@@ -866,26 +902,6 @@ template<> EIGEN_STRONG_INLINE Packet16b preverse(const Packet16b& a) {
|
||||
#endif
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pabs(const Packet4f& a)
|
||||
{
|
||||
const Packet4f mask = _mm_castsi128_ps(_mm_setr_epi32(0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF));
|
||||
return _mm_and_ps(a,mask);
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pabs(const Packet2d& a)
|
||||
{
|
||||
const Packet2d mask = _mm_castsi128_pd(_mm_setr_epi32(0xFFFFFFFF,0x7FFFFFFF,0xFFFFFFFF,0x7FFFFFFF));
|
||||
return _mm_and_pd(a,mask);
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE Packet4i pabs(const Packet4i& a)
|
||||
{
|
||||
#ifdef EIGEN_VECTORIZE_SSSE3
|
||||
return _mm_abs_epi32(a);
|
||||
#else
|
||||
Packet4i aux = _mm_srai_epi32(a,31);
|
||||
return _mm_sub_epi32(_mm_xor_si128(a,aux),aux);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pfrexp<Packet4f>(const Packet4f& a, Packet4f& exponent) {
|
||||
return pfrexp_generic(a,exponent);
|
||||
}
|
||||
|
||||
@@ -265,111 +265,6 @@ struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_NEQ> : binary_op_base<LhsScalar,Rh
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a!=b;}
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functors for comparison of two scalars and cast the output from boolean to input datatype
|
||||
*/
|
||||
template<typename LhsScalar, typename RhsScalar, ComparisonName cmp> struct scalar_cmp_with_cast_op;
|
||||
|
||||
template<typename LhsScalar, typename RhsScalar, ComparisonName cmp>
|
||||
struct functor_traits<scalar_cmp_with_cast_op<LhsScalar,RhsScalar, cmp> > {
|
||||
enum {
|
||||
Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
|
||||
PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasCmp
|
||||
};
|
||||
};
|
||||
|
||||
template<typename LhsScalar, typename RhsScalar>
|
||||
struct scalar_cmp_with_cast_op<LhsScalar, RhsScalar, cmp_EQ> : binary_op_base<LhsScalar,RhsScalar>
|
||||
{
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_cmp_with_cast_op>::ReturnType result_type;
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_with_cast_op)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
|
||||
if(a==b) return static_cast<result_type>(1);
|
||||
else return static_cast<result_type>(0);
|
||||
}
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{ return internal::pselect(internal::pcmp_eq(a,b), internal::pset1<Packet>(static_cast<result_type>(1)), internal::pzero(a)); }
|
||||
};
|
||||
template<typename LhsScalar, typename RhsScalar>
|
||||
struct scalar_cmp_with_cast_op<LhsScalar, RhsScalar, cmp_LT> : binary_op_base<LhsScalar,RhsScalar>
|
||||
{
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_cmp_with_cast_op>::ReturnType result_type;
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_with_cast_op)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
|
||||
if(a<b) return static_cast<result_type>(1);
|
||||
else return static_cast<result_type>(0);
|
||||
}
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{ return internal::pselect(internal::pcmp_lt(a,b), internal::pset1<Packet>(static_cast<result_type>(1)), internal::pzero(a)); }
|
||||
};
|
||||
template<typename LhsScalar, typename RhsScalar>
|
||||
struct scalar_cmp_with_cast_op<LhsScalar, RhsScalar, cmp_LE> : binary_op_base<LhsScalar,RhsScalar>
|
||||
{
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_cmp_with_cast_op>::ReturnType result_type;
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_with_cast_op)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
|
||||
if(a<=b) return static_cast<result_type>(1);
|
||||
else return static_cast<result_type>(0);
|
||||
}
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{ return internal::pselect(internal::pcmp_le(a,b), internal::pset1<Packet>(static_cast<result_type>(1)), internal::pzero(a)); }
|
||||
};
|
||||
template<typename LhsScalar, typename RhsScalar>
|
||||
struct scalar_cmp_with_cast_op<LhsScalar, RhsScalar, cmp_GT> : binary_op_base<LhsScalar,RhsScalar>
|
||||
{
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_cmp_with_cast_op>::ReturnType result_type;
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_with_cast_op)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
|
||||
if(a>b) return static_cast<result_type>(1);
|
||||
else return static_cast<result_type>(0);
|
||||
}
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{ return internal::pselect(internal::pcmp_le(a,b), internal::pzero(a), internal::pset1<Packet>(static_cast<result_type>(1))); }
|
||||
};
|
||||
template<typename LhsScalar, typename RhsScalar>
|
||||
struct scalar_cmp_with_cast_op<LhsScalar, RhsScalar, cmp_GE> : binary_op_base<LhsScalar,RhsScalar>
|
||||
{
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_cmp_with_cast_op>::ReturnType result_type;
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_with_cast_op)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
|
||||
if(a>=b) return static_cast<result_type>(1);
|
||||
else return static_cast<result_type>(0);
|
||||
}
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{ return internal::pselect(internal::pcmp_lt(a,b), internal::pzero(a), internal::pset1<Packet>(static_cast<result_type>(1))); }
|
||||
};
|
||||
template<typename LhsScalar, typename RhsScalar>
|
||||
struct scalar_cmp_with_cast_op<LhsScalar, RhsScalar, cmp_UNORD> : binary_op_base<LhsScalar,RhsScalar>
|
||||
{
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_cmp_with_cast_op>::ReturnType result_type;
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_with_cast_op)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
|
||||
if(a<=b || b<=a) return static_cast<result_type>(0);
|
||||
else return static_cast<result_type>(1);
|
||||
}
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{ return internal::pselect(por(internal::pcmp_le(a,b), internal::pcmp_le(b,a)), internal::pzero(a), internal::pset1<Packet>(static_cast<result_type>(1))); }
|
||||
};
|
||||
template<typename LhsScalar, typename RhsScalar>
|
||||
struct scalar_cmp_with_cast_op<LhsScalar, RhsScalar, cmp_NEQ> : binary_op_base<LhsScalar,RhsScalar>
|
||||
{
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_cmp_with_cast_op>::ReturnType result_type;
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_with_cast_op)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
|
||||
if(a!=b) return static_cast<result_type>(1);
|
||||
else return static_cast<result_type>(0);
|
||||
}
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{ return internal::pselect(internal::pcmp_eq(a,b), internal::pzero(a), internal::pset1<Packet>(static_cast<result_type>(1))); }
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the hypot of two \b positive \b and \b real scalars
|
||||
*
|
||||
|
||||
@@ -72,7 +72,7 @@ template<typename T>
|
||||
struct functor_traits<std::not_equal_to<T> >
|
||||
{ enum { Cost = 1, PacketAccess = false }; };
|
||||
|
||||
#if (__cplusplus < 201103L) && (EIGEN_COMP_MSVC <= 1900)
|
||||
#if (EIGEN_COMP_CXXVER < 11)
|
||||
// std::binder* are deprecated since c++11 and will be removed in c++17
|
||||
template<typename T>
|
||||
struct functor_traits<std::binder2nd<T> >
|
||||
@@ -83,7 +83,7 @@ struct functor_traits<std::binder1st<T> >
|
||||
{ enum { Cost = functor_traits<T>::Cost, PacketAccess = false }; };
|
||||
#endif
|
||||
|
||||
#if (__cplusplus < 201703L) && (EIGEN_COMP_MSVC < 1910)
|
||||
#if (EIGEN_COMP_CXXVER < 17)
|
||||
// std::unary_negate is deprecated since c++17 and will be removed in c++20
|
||||
template<typename T>
|
||||
struct functor_traits<std::unary_negate<T> >
|
||||
|
||||
@@ -44,6 +44,9 @@
|
||||
#if __clang_major__ >= 3 && __clang_minor__ >= 5
|
||||
#pragma clang diagnostic ignored "-Wabsolute-value"
|
||||
#endif
|
||||
#if __clang_major__ >= 10
|
||||
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion"
|
||||
#endif
|
||||
#if ( defined(__ALTIVEC__) || defined(__VSX__) ) && __cplusplus < 201103L
|
||||
// warning: generic selections are a C11-specific feature
|
||||
// ignoring warnings thrown at vec_ctf in Altivec/PacketMath.h
|
||||
|
||||
@@ -78,7 +78,7 @@ template<typename T, typename EnableIf = void> struct get_compile_time_incr {
|
||||
|
||||
// Analogue of std::get<0>(x), but tailored for our needs.
|
||||
template<typename T>
|
||||
Index first(const T& x) { return x.first(); }
|
||||
EIGEN_CONSTEXPR Index first(const T& x) EIGEN_NOEXCEPT { return x.first(); }
|
||||
|
||||
// IndexedViewCompatibleType/makeIndexedViewCompatible turn an arbitrary object of type T into something usable by MatrixSlice
|
||||
// The generic implementation is a no-op
|
||||
@@ -100,8 +100,8 @@ struct SingleRange {
|
||||
};
|
||||
SingleRange(Index val) : m_value(val) {}
|
||||
Index operator[](Index) const { return m_value; }
|
||||
Index size() const { return 1; }
|
||||
Index first() const { return m_value; }
|
||||
static EIGEN_CONSTEXPR Index size() EIGEN_NOEXCEPT { return 1; }
|
||||
Index first() const EIGEN_NOEXCEPT { return m_value; }
|
||||
Index m_value;
|
||||
};
|
||||
|
||||
@@ -141,9 +141,9 @@ template<int XprSize>
|
||||
struct AllRange {
|
||||
enum { SizeAtCompileTime = XprSize };
|
||||
AllRange(Index size = XprSize) : m_size(size) {}
|
||||
Index operator[](Index i) const { return i; }
|
||||
Index size() const { return m_size.value(); }
|
||||
Index first() const { return 0; }
|
||||
EIGEN_CONSTEXPR Index operator[](Index i) const EIGEN_NOEXCEPT { return i; }
|
||||
EIGEN_CONSTEXPR Index size() const EIGEN_NOEXCEPT { return m_size.value(); }
|
||||
EIGEN_CONSTEXPR Index first() const EIGEN_NOEXCEPT { return 0; }
|
||||
variable_if_dynamic<Index,XprSize> m_size;
|
||||
};
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ template<int N> class FixedInt
|
||||
{
|
||||
public:
|
||||
static const int value = N;
|
||||
operator int() const { return value; }
|
||||
EIGEN_CONSTEXPR operator int() const { return value; }
|
||||
FixedInt() {}
|
||||
FixedInt( VariableAndFixedInt<N> other) {
|
||||
#ifndef EIGEN_INTERNAL_DEBUGGING
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
#define EIGEN_WORLD_VERSION 3
|
||||
#define EIGEN_MAJOR_VERSION 3
|
||||
#define EIGEN_MINOR_VERSION 90
|
||||
#define EIGEN_MAJOR_VERSION 4
|
||||
#define EIGEN_MINOR_VERSION 99
|
||||
|
||||
#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
|
||||
(EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
|
||||
@@ -226,7 +226,7 @@
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#if defined(__x86_64__) || defined(_M_X64) || defined(__amd64)
|
||||
#if defined(__x86_64__) || (defined(_M_X64) && !defined(_M_ARM64EC)) || defined(__amd64)
|
||||
#define EIGEN_ARCH_x86_64 1
|
||||
#else
|
||||
#define EIGEN_ARCH_x86_64 0
|
||||
@@ -252,7 +252,7 @@
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_ARCH_ARM64 set to 1 if the architecture is ARM64
|
||||
#if defined(__aarch64__)
|
||||
#if defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)
|
||||
#define EIGEN_ARCH_ARM64 1
|
||||
#else
|
||||
#define EIGEN_ARCH_ARM64 0
|
||||
@@ -265,6 +265,14 @@
|
||||
#define EIGEN_ARCH_ARM_OR_ARM64 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_ARCH_ARMV8 set to 1 if the architecture is armv8 or greater.
|
||||
#if EIGEN_ARCH_ARM_OR_ARM64 && defined(__ARM_ARCH) && __ARM_ARCH >= 8
|
||||
#define EIGEN_ARCH_ARMV8 1
|
||||
#else
|
||||
#define EIGEN_ARCH_ARMV8 0
|
||||
#endif
|
||||
|
||||
|
||||
/// \internal EIGEN_HAS_ARM64_FP16 set to 1 if the architecture provides an IEEE
|
||||
/// compliant Arm fp16 type
|
||||
#if EIGEN_ARCH_ARM64
|
||||
@@ -597,18 +605,36 @@
|
||||
#define EIGEN_HAS_STATIC_ARRAY_TEMPLATE 0
|
||||
#endif
|
||||
|
||||
// The macro EIGEN_CPLUSPLUS is a replacement for __cplusplus/_MSVC_LANG that
|
||||
// works for both platforms, indicating the C++ standard version number.
|
||||
//
|
||||
// With MSVC, without defining /Zc:__cplusplus, the __cplusplus macro will
|
||||
// report 199711L regardless of the language standard specified via /std.
|
||||
// We need to rely on _MSVC_LANG instead, which is only available after
|
||||
// VS2015.3.
|
||||
#if EIGEN_COMP_MSVC_LANG > 0
|
||||
#define EIGEN_CPLUSPLUS EIGEN_COMP_MSVC_LANG
|
||||
#elif EIGEN_COMP_MSVC >= 1900
|
||||
#define EIGEN_CPLUSPLUS 201103L
|
||||
#elif defined(__cplusplus)
|
||||
#define EIGEN_CPLUSPLUS __cplusplus
|
||||
#else
|
||||
#define EIGEN_CPLUSPLUS 0
|
||||
#endif
|
||||
|
||||
// The macro EIGEN_COMP_CXXVER defines the c++ verson expected by the compiler.
|
||||
// For instance, if compiling with gcc and -std=c++17, then EIGEN_COMP_CXXVER
|
||||
// is defined to 17.
|
||||
#if (defined(__cplusplus) && (__cplusplus > 201402L) || EIGEN_COMP_MSVC_LANG > 201402L)
|
||||
#define EIGEN_COMP_CXXVER 17
|
||||
#elif (defined(__cplusplus) && (__cplusplus > 201103L) || EIGEN_COMP_MSVC >= 1910)
|
||||
#define EIGEN_COMP_CXXVER 14
|
||||
#elif (defined(__cplusplus) && (__cplusplus >= 201103L) || EIGEN_COMP_MSVC >= 1900)
|
||||
#define EIGEN_COMP_CXXVER 11
|
||||
#if EIGEN_CPLUSPLUS > 201703L
|
||||
#define EIGEN_COMP_CXXVER 20
|
||||
#elif EIGEN_CPLUSPLUS > 201402L
|
||||
#define EIGEN_COMP_CXXVER 17
|
||||
#elif EIGEN_CPLUSPLUS > 201103L
|
||||
#define EIGEN_COMP_CXXVER 14
|
||||
#elif EIGEN_CPLUSPLUS >= 201103L
|
||||
#define EIGEN_COMP_CXXVER 11
|
||||
#else
|
||||
#define EIGEN_COMP_CXXVER 03
|
||||
#define EIGEN_COMP_CXXVER 03
|
||||
#endif
|
||||
|
||||
|
||||
@@ -633,8 +659,7 @@
|
||||
#ifndef EIGEN_HAS_RVALUE_REFERENCES
|
||||
#if EIGEN_MAX_CPP_VER>=11 && \
|
||||
(__has_feature(cxx_rvalue_references) || \
|
||||
(defined(__cplusplus) && __cplusplus >= 201103L) || \
|
||||
(EIGEN_COMP_MSVC >= 1600))
|
||||
(EIGEN_COMP_CXXVER >= 11) || (EIGEN_COMP_MSVC >= 1600))
|
||||
#define EIGEN_HAS_RVALUE_REFERENCES 1
|
||||
#else
|
||||
#define EIGEN_HAS_RVALUE_REFERENCES 0
|
||||
@@ -660,14 +685,33 @@
|
||||
// result_of was deprecated in c++17 and removed in c++ 20
|
||||
#ifndef EIGEN_HAS_STD_RESULT_OF
|
||||
#if EIGEN_MAX_CPP_VER >= 11 && \
|
||||
((defined(__cplusplus) && __cplusplus >= 201103L && __cplusplus < 201703L) || \
|
||||
__has_feature(cxx_lambdas))
|
||||
(defined(__cplusplus) && __cplusplus >= 201103L && __cplusplus < 201703L)
|
||||
#define EIGEN_HAS_STD_RESULT_OF 1
|
||||
#else
|
||||
#define EIGEN_HAS_STD_RESULT_OF 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Does the compiler support std::hash?
|
||||
#ifndef EIGEN_HAS_STD_HASH
|
||||
// The std::hash struct is defined in C++11 but is not labelled as a __device__
|
||||
// function and is not constexpr, so cannot be used on device.
|
||||
#if EIGEN_HAS_CXX11 && !defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
#define EIGEN_HAS_STD_HASH 1
|
||||
#else
|
||||
#define EIGEN_HAS_STD_HASH 0
|
||||
#endif
|
||||
#endif // EIGEN_HAS_STD_HASH
|
||||
|
||||
#ifndef EIGEN_HAS_STD_INVOKE_RESULT
|
||||
#if EIGEN_MAX_CPP_VER >= 17 && \
|
||||
(defined(__cplusplus) && __cplusplus >= 201703L)
|
||||
#define EIGEN_HAS_STD_INVOKE_RESULT 1
|
||||
#else
|
||||
#define EIGEN_HAS_STD_INVOKE_RESULT 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef EIGEN_HAS_ALIGNAS
|
||||
#if EIGEN_MAX_CPP_VER>=11 && EIGEN_HAS_CXX11 && \
|
||||
( __has_feature(cxx_alignas) \
|
||||
@@ -700,12 +744,12 @@
|
||||
|
||||
// Does the compiler support variadic templates?
|
||||
#ifndef EIGEN_HAS_VARIADIC_TEMPLATES
|
||||
#if EIGEN_MAX_CPP_VER>=11 && (__cplusplus > 199711L || EIGEN_COMP_MSVC >= 1900) \
|
||||
#if EIGEN_MAX_CPP_VER>=11 && (EIGEN_COMP_CXXVER >= 11) \
|
||||
&& (!defined(__NVCC__) || !EIGEN_ARCH_ARM_OR_ARM64 || (EIGEN_COMP_NVCC >= 80000) )
|
||||
// ^^ Disable the use of variadic templates when compiling with versions of nvcc older than 8.0 on ARM devices:
|
||||
// this prevents nvcc from crashing when compiling Eigen on Tegra X1
|
||||
#define EIGEN_HAS_VARIADIC_TEMPLATES 1
|
||||
#elif EIGEN_MAX_CPP_VER>=11 && (__cplusplus > 199711L || EIGEN_COMP_MSVC >= 1900) && defined(SYCL_DEVICE_ONLY)
|
||||
#elif EIGEN_MAX_CPP_VER>=11 && (EIGEN_COMP_CXXVER >= 11) && defined(SYCL_DEVICE_ONLY)
|
||||
#define EIGEN_HAS_VARIADIC_TEMPLATES 1
|
||||
#else
|
||||
#define EIGEN_HAS_VARIADIC_TEMPLATES 0
|
||||
@@ -716,12 +760,12 @@
|
||||
#ifndef EIGEN_HAS_CONSTEXPR
|
||||
#if defined(EIGEN_CUDACC)
|
||||
// Const expressions are supported provided that c++11 is enabled and we're using either clang or nvcc 7.5 or above
|
||||
#if EIGEN_MAX_CPP_VER>=14 && (__cplusplus > 199711L && (EIGEN_COMP_CLANG || EIGEN_COMP_NVCC >= 70500))
|
||||
#if EIGEN_MAX_CPP_VER>=14 && (EIGEN_COMP_CXXVER >= 11 && (EIGEN_COMP_CLANG || EIGEN_COMP_NVCC >= 70500))
|
||||
#define EIGEN_HAS_CONSTEXPR 1
|
||||
#endif
|
||||
#elif EIGEN_MAX_CPP_VER>=14 && (__has_feature(cxx_relaxed_constexpr) || (defined(__cplusplus) && __cplusplus >= 201402L) || \
|
||||
(EIGEN_GNUC_AT_LEAST(4,8) && (__cplusplus > 199711L)) || \
|
||||
(EIGEN_COMP_CLANG >= 306 && (__cplusplus > 199711L)))
|
||||
#elif EIGEN_MAX_CPP_VER>=14 && (__has_feature(cxx_relaxed_constexpr) || (EIGEN_COMP_CXXVER >= 14) || \
|
||||
(EIGEN_GNUC_AT_LEAST(4,8) && (EIGEN_COMP_CXXVER >= 11)) || \
|
||||
(EIGEN_COMP_CLANG >= 306 && (EIGEN_COMP_CXXVER >= 11)))
|
||||
#define EIGEN_HAS_CONSTEXPR 1
|
||||
#endif
|
||||
|
||||
@@ -740,7 +784,7 @@
|
||||
// Does the compiler support C++11 math?
|
||||
// Let's be conservative and enable the default C++11 implementation only if we are sure it exists
|
||||
#ifndef EIGEN_HAS_CXX11_MATH
|
||||
#if EIGEN_MAX_CPP_VER>=11 && ((__cplusplus > 201103L) || (__cplusplus >= 201103L) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_CLANG || EIGEN_COMP_MSVC || EIGEN_COMP_ICC) \
|
||||
#if EIGEN_MAX_CPP_VER>=11 && ((EIGEN_COMP_CXXVER > 11) || (EIGEN_COMP_CXXVER == 11) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_CLANG || EIGEN_COMP_MSVC || EIGEN_COMP_ICC) \
|
||||
&& (EIGEN_ARCH_i386_OR_x86_64) && (EIGEN_OS_GNULINUX || EIGEN_OS_WIN_STRICT || EIGEN_OS_MAC))
|
||||
#define EIGEN_HAS_CXX11_MATH 1
|
||||
#else
|
||||
@@ -751,9 +795,8 @@
|
||||
// Does the compiler support proper C++11 containers?
|
||||
#ifndef EIGEN_HAS_CXX11_CONTAINERS
|
||||
#if EIGEN_MAX_CPP_VER>=11 && \
|
||||
((__cplusplus > 201103L) \
|
||||
|| ((__cplusplus >= 201103L) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_CLANG || EIGEN_COMP_ICC>=1400)) \
|
||||
|| EIGEN_COMP_MSVC >= 1900)
|
||||
((EIGEN_COMP_CXXVER > 11) \
|
||||
|| ((EIGEN_COMP_CXXVER == 11) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_CLANG || EIGEN_COMP_MSVC || EIGEN_COMP_ICC>=1400)))
|
||||
#define EIGEN_HAS_CXX11_CONTAINERS 1
|
||||
#else
|
||||
#define EIGEN_HAS_CXX11_CONTAINERS 0
|
||||
@@ -764,9 +807,8 @@
|
||||
#ifndef EIGEN_HAS_CXX11_NOEXCEPT
|
||||
#if EIGEN_MAX_CPP_VER>=11 && \
|
||||
(__has_feature(cxx_noexcept) \
|
||||
|| (__cplusplus > 201103L) \
|
||||
|| ((__cplusplus >= 201103L) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_CLANG || EIGEN_COMP_ICC>=1400)) \
|
||||
|| EIGEN_COMP_MSVC >= 1900)
|
||||
|| (EIGEN_COMP_CXXVER > 11) \
|
||||
|| ((EIGEN_COMP_CXXVER == 11) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_CLANG || EIGEN_COMP_MSVC || EIGEN_COMP_ICC>=1400)))
|
||||
#define EIGEN_HAS_CXX11_NOEXCEPT 1
|
||||
#else
|
||||
#define EIGEN_HAS_CXX11_NOEXCEPT 0
|
||||
@@ -776,8 +818,8 @@
|
||||
#ifndef EIGEN_HAS_CXX11_ATOMIC
|
||||
#if EIGEN_MAX_CPP_VER>=11 && \
|
||||
(__has_feature(cxx_atomic) \
|
||||
|| (__cplusplus > 201103L) \
|
||||
|| ((__cplusplus >= 201103L) && (EIGEN_COMP_MSVC==0 || EIGEN_COMP_MSVC >= 1700)))
|
||||
|| (EIGEN_COMP_CXXVER > 11) \
|
||||
|| ((EIGEN_COMP_CXXVER == 11) && (EIGEN_COMP_MSVC==0 || EIGEN_COMP_MSVC >= 1700)))
|
||||
#define EIGEN_HAS_CXX11_ATOMIC 1
|
||||
#else
|
||||
#define EIGEN_HAS_CXX11_ATOMIC 0
|
||||
@@ -786,7 +828,7 @@
|
||||
|
||||
#ifndef EIGEN_HAS_CXX11_OVERRIDE_FINAL
|
||||
#if EIGEN_MAX_CPP_VER>=11 && \
|
||||
(__cplusplus >= 201103L || EIGEN_COMP_MSVC >= 1700)
|
||||
(EIGEN_COMP_CXXVER >= 11 || EIGEN_COMP_MSVC >= 1700)
|
||||
#define EIGEN_HAS_CXX11_OVERRIDE_FINAL 1
|
||||
#else
|
||||
#define EIGEN_HAS_CXX11_OVERRIDE_FINAL 0
|
||||
@@ -863,7 +905,7 @@
|
||||
// but it still doesn't use GCC's always_inline. This is useful in (common) situations where MSVC needs forceinline
|
||||
// but GCC is still doing fine with just inline.
|
||||
#ifndef EIGEN_STRONG_INLINE
|
||||
#if EIGEN_COMP_MSVC || EIGEN_COMP_ICC
|
||||
#if (EIGEN_COMP_MSVC || EIGEN_COMP_ICC) && !defined(EIGEN_GPUCC)
|
||||
#define EIGEN_STRONG_INLINE __forceinline
|
||||
#else
|
||||
#define EIGEN_STRONG_INLINE inline
|
||||
@@ -1036,6 +1078,67 @@ namespace Eigen {
|
||||
#endif
|
||||
|
||||
|
||||
// Acts as a barrier preventing operations involving `X` from crossing. This
|
||||
// occurs, for example, in the fast rounding trick where a magic constant is
|
||||
// added then subtracted, which is otherwise compiled away with -ffast-math.
|
||||
//
|
||||
// See bug 1674
|
||||
#if !defined(EIGEN_OPTIMIZATION_BARRIER)
|
||||
#if EIGEN_COMP_GNUC
|
||||
// According to https://gcc.gnu.org/onlinedocs/gcc/Constraints.html:
|
||||
// X: Any operand whatsoever.
|
||||
// r: A register operand is allowed provided that it is in a general
|
||||
// register.
|
||||
// g: Any register, memory or immediate integer operand is allowed, except
|
||||
// for registers that are not general registers.
|
||||
// w: (AArch32/AArch64) Floating point register, Advanced SIMD vector
|
||||
// register or SVE vector register.
|
||||
// x: (SSE) Any SSE register.
|
||||
// (AArch64) Like w, but restricted to registers 0 to 15 inclusive.
|
||||
// v: (PowerPC) An Altivec vector register.
|
||||
// wa:(PowerPC) A VSX register.
|
||||
//
|
||||
// "X" (uppercase) should work for all cases, though this seems to fail for
|
||||
// some versions of GCC for arm/aarch64 with
|
||||
// "error: inconsistent operand constraints in an 'asm'"
|
||||
// Clang x86_64/arm/aarch64 seems to require "g" to support both scalars and
|
||||
// vectors, otherwise
|
||||
// "error: non-trivial scalar-to-vector conversion, possible invalid
|
||||
// constraint for vector type"
|
||||
//
|
||||
// GCC for ppc64le generates an internal compiler error with x/X/g.
|
||||
// GCC for AVX generates an internal compiler error with X.
|
||||
//
|
||||
// Tested on icc/gcc/clang for sse, avx, avx2, avx512dq
|
||||
// gcc for arm, aarch64,
|
||||
// gcc for ppc64le,
|
||||
// both vectors and scalars.
|
||||
//
|
||||
// Note that this is restricted to plain types - this will not work
|
||||
// directly for std::complex<T>, Eigen::half, Eigen::bfloat16. For these,
|
||||
// you will need to apply to the underlying POD type.
|
||||
#if EIGEN_ARCH_PPC && EIGEN_COMP_GNUC_STRICT
|
||||
// This seems to be broken on clang. Packet4f is loaded into a single
|
||||
// register rather than a vector, zeroing out some entries. Integer
|
||||
// types also generate a compile error.
|
||||
// General, Altivec, VSX.
|
||||
#define EIGEN_OPTIMIZATION_BARRIER(X) __asm__ ("" : "+r,v,wa" (X));
|
||||
#elif EIGEN_ARCH_ARM_OR_ARM64
|
||||
// General, NEON.
|
||||
#define EIGEN_OPTIMIZATION_BARRIER(X) __asm__ ("" : "+g,w" (X));
|
||||
#elif EIGEN_ARCH_i386_OR_x86_64
|
||||
// General, SSE.
|
||||
#define EIGEN_OPTIMIZATION_BARRIER(X) __asm__ ("" : "+g,x" (X));
|
||||
#else
|
||||
// Not implemented for other architectures.
|
||||
#define EIGEN_OPTIMIZATION_BARRIER(X)
|
||||
#endif
|
||||
#else
|
||||
// Not implemented for other compilers.
|
||||
#define EIGEN_OPTIMIZATION_BARRIER(X)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if EIGEN_COMP_MSVC
|
||||
// NOTE MSVC often gives C4127 warnings with compiletime if statements. See bug 1362.
|
||||
// This workaround is ugly, but it does the job.
|
||||
|
||||
@@ -780,32 +780,45 @@ template<typename T> void swap(scoped_array<T> &a,scoped_array<T> &b)
|
||||
|
||||
#else
|
||||
|
||||
#if EIGEN_MAX_ALIGN_BYTES!=0
|
||||
// HIP does not support new/delete on device.
|
||||
#if EIGEN_MAX_ALIGN_BYTES!=0 && !defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
|
||||
EIGEN_DEVICE_FUNC \
|
||||
void* operator new(std::size_t size, const std::nothrow_t&) EIGEN_NO_THROW { \
|
||||
EIGEN_TRY { return Eigen::internal::conditional_aligned_malloc<NeedsToAlign>(size); } \
|
||||
EIGEN_CATCH (...) { return 0; } \
|
||||
}
|
||||
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) \
|
||||
EIGEN_DEVICE_FUNC \
|
||||
void *operator new(std::size_t size) { \
|
||||
return Eigen::internal::conditional_aligned_malloc<NeedsToAlign>(size); \
|
||||
} \
|
||||
EIGEN_DEVICE_FUNC \
|
||||
void *operator new[](std::size_t size) { \
|
||||
return Eigen::internal::conditional_aligned_malloc<NeedsToAlign>(size); \
|
||||
} \
|
||||
EIGEN_DEVICE_FUNC \
|
||||
void operator delete(void * ptr) EIGEN_NO_THROW { Eigen::internal::conditional_aligned_free<NeedsToAlign>(ptr); } \
|
||||
EIGEN_DEVICE_FUNC \
|
||||
void operator delete[](void * ptr) EIGEN_NO_THROW { Eigen::internal::conditional_aligned_free<NeedsToAlign>(ptr); } \
|
||||
EIGEN_DEVICE_FUNC \
|
||||
void operator delete(void * ptr, std::size_t /* sz */) EIGEN_NO_THROW { Eigen::internal::conditional_aligned_free<NeedsToAlign>(ptr); } \
|
||||
EIGEN_DEVICE_FUNC \
|
||||
void operator delete[](void * ptr, std::size_t /* sz */) EIGEN_NO_THROW { Eigen::internal::conditional_aligned_free<NeedsToAlign>(ptr); } \
|
||||
/* in-place new and delete. since (at least afaik) there is no actual */ \
|
||||
/* memory allocated we can safely let the default implementation handle */ \
|
||||
/* this particular case. */ \
|
||||
EIGEN_DEVICE_FUNC \
|
||||
static void *operator new(std::size_t size, void *ptr) { return ::operator new(size,ptr); } \
|
||||
EIGEN_DEVICE_FUNC \
|
||||
static void *operator new[](std::size_t size, void* ptr) { return ::operator new[](size,ptr); } \
|
||||
EIGEN_DEVICE_FUNC \
|
||||
void operator delete(void * memory, void *ptr) EIGEN_NO_THROW { return ::operator delete(memory,ptr); } \
|
||||
EIGEN_DEVICE_FUNC \
|
||||
void operator delete[](void * memory, void *ptr) EIGEN_NO_THROW { return ::operator delete[](memory,ptr); } \
|
||||
/* nothrow-new (returns zero instead of std::bad_alloc) */ \
|
||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
|
||||
EIGEN_DEVICE_FUNC \
|
||||
void operator delete(void *ptr, const std::nothrow_t&) EIGEN_NO_THROW { \
|
||||
Eigen::internal::conditional_aligned_free<NeedsToAlign>(ptr); \
|
||||
} \
|
||||
|
||||
@@ -275,7 +275,7 @@ template<bool Condition, typename T=void> struct enable_if;
|
||||
template<typename T> struct enable_if<true,T>
|
||||
{ typedef T type; };
|
||||
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE) && !EIGEN_HAS_CXX11
|
||||
#if !defined(__FLT_EPSILON__)
|
||||
#define __FLT_EPSILON__ FLT_EPSILON
|
||||
#define __DBL_EPSILON__ DBL_EPSILON
|
||||
@@ -286,7 +286,7 @@ namespace device {
|
||||
template<typename T> struct numeric_limits
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static T epsilon() { return 0; }
|
||||
static EIGEN_CONSTEXPR T epsilon() { return 0; }
|
||||
static T (max)() { assert(false && "Highest not supported for this type"); }
|
||||
static T (min)() { assert(false && "Lowest not supported for this type"); }
|
||||
static T infinity() { assert(false && "Infinity not supported for this type"); }
|
||||
@@ -294,7 +294,7 @@ template<typename T> struct numeric_limits
|
||||
};
|
||||
template<> struct numeric_limits<float>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static float epsilon() { return __FLT_EPSILON__; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static float (max)() {
|
||||
@@ -304,7 +304,7 @@ template<> struct numeric_limits<float>
|
||||
return HIPRT_MAX_NORMAL_F;
|
||||
#endif
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static float (min)() { return FLT_MIN; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static float infinity() {
|
||||
@@ -325,11 +325,11 @@ template<> struct numeric_limits<float>
|
||||
};
|
||||
template<> struct numeric_limits<double>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static double epsilon() { return __DBL_EPSILON__; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static double (max)() { return DBL_MAX; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static double (min)() { return DBL_MIN; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static double infinity() {
|
||||
@@ -350,71 +350,71 @@ template<> struct numeric_limits<double>
|
||||
};
|
||||
template<> struct numeric_limits<int>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static int epsilon() { return 0; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static int (max)() { return INT_MAX; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static int (min)() { return INT_MIN; }
|
||||
};
|
||||
template<> struct numeric_limits<unsigned int>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static unsigned int epsilon() { return 0; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static unsigned int (max)() { return UINT_MAX; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static unsigned int (min)() { return 0; }
|
||||
};
|
||||
template<> struct numeric_limits<long>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static long epsilon() { return 0; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static long (max)() { return LONG_MAX; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static long (min)() { return LONG_MIN; }
|
||||
};
|
||||
template<> struct numeric_limits<unsigned long>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static unsigned long epsilon() { return 0; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static unsigned long (max)() { return ULONG_MAX; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static unsigned long (min)() { return 0; }
|
||||
};
|
||||
template<> struct numeric_limits<long long>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static long long epsilon() { return 0; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static long long (max)() { return LLONG_MAX; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static long long (min)() { return LLONG_MIN; }
|
||||
};
|
||||
template<> struct numeric_limits<unsigned long long>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static unsigned long long epsilon() { return 0; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static unsigned long long (max)() { return ULLONG_MAX; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static unsigned long long (min)() { return 0; }
|
||||
};
|
||||
template<> struct numeric_limits<bool>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static bool epsilon() { return false; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static bool (max)() { return true; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static bool (min)() { return false; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // defined(EIGEN_GPU_COMPILE_PHASE) && !EIGEN_HAS_CXX11
|
||||
|
||||
/** \internal
|
||||
* A base class do disable default copy ctor and copy assignment operator.
|
||||
@@ -476,19 +476,35 @@ template<typename T, std::size_t N> struct array_size<std::array<T,N> > {
|
||||
*
|
||||
*/
|
||||
template<typename T>
|
||||
Index size(const T& x) { return x.size(); }
|
||||
EIGEN_CONSTEXPR Index size(const T& x) { return x.size(); }
|
||||
|
||||
template<typename T,std::size_t N>
|
||||
Index size(const T (&) [N]) { return N; }
|
||||
EIGEN_CONSTEXPR Index size(const T (&) [N]) { return N; }
|
||||
|
||||
/** \internal
|
||||
* Convenient struct to get the result type of a unary or binary functor.
|
||||
*
|
||||
* It supports both the current STL mechanism (using the result_type member) as well as
|
||||
* upcoming next STL generation (using a templated result member).
|
||||
* If none of these members is provided, then the type of the first argument is returned. FIXME, that behavior is a pretty bad hack.
|
||||
* Convenient struct to get the result type of a nullary, unary, binary, or
|
||||
* ternary functor.
|
||||
*
|
||||
* Pre C++11:
|
||||
* Supports both a Func::result_type member and templated
|
||||
* Func::result<Func(ArgTypes...)>::type member.
|
||||
*
|
||||
* If none of these members is provided, then the type of the first
|
||||
* argument is returned.
|
||||
*
|
||||
* Post C++11:
|
||||
* This uses std::result_of. However, note the `type` member removes
|
||||
* const and converts references/pointers to their corresponding value type.
|
||||
*/
|
||||
#if EIGEN_HAS_STD_RESULT_OF
|
||||
#if EIGEN_HAS_STD_INVOKE_RESULT
|
||||
template<typename T> struct result_of;
|
||||
|
||||
template<typename F, typename... ArgTypes>
|
||||
struct result_of<F(ArgTypes...)> {
|
||||
typedef typename std::invoke_result<F, ArgTypes...>::type type1;
|
||||
typedef typename remove_all<type1>::type type;
|
||||
};
|
||||
#elif EIGEN_HAS_STD_RESULT_OF
|
||||
template<typename T> struct result_of {
|
||||
typedef typename std::result_of<T>::type type1;
|
||||
typedef typename remove_all<type1>::type type;
|
||||
@@ -500,6 +516,28 @@ struct has_none {int a[1];};
|
||||
struct has_std_result_type {int a[2];};
|
||||
struct has_tr1_result {int a[3];};
|
||||
|
||||
template<typename Func, int SizeOf>
|
||||
struct nullary_result_of_select {};
|
||||
|
||||
template<typename Func>
|
||||
struct nullary_result_of_select<Func, sizeof(has_std_result_type)> {typedef typename Func::result_type type;};
|
||||
|
||||
template<typename Func>
|
||||
struct nullary_result_of_select<Func, sizeof(has_tr1_result)> {typedef typename Func::template result<Func()>::type type;};
|
||||
|
||||
template<typename Func>
|
||||
struct result_of<Func()> {
|
||||
template<typename T>
|
||||
static has_std_result_type testFunctor(T const *, typename T::result_type const * = 0);
|
||||
template<typename T>
|
||||
static has_tr1_result testFunctor(T const *, typename T::template result<T()>::type const * = 0);
|
||||
static has_none testFunctor(...);
|
||||
|
||||
// note that the following indirection is needed for gcc-3.3
|
||||
enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
|
||||
typedef typename nullary_result_of_select<Func, FunctorType>::type type;
|
||||
};
|
||||
|
||||
template<typename Func, typename ArgType, int SizeOf=sizeof(has_none)>
|
||||
struct unary_result_of_select {typedef typename internal::remove_all<ArgType>::type type;};
|
||||
|
||||
@@ -569,6 +607,45 @@ struct result_of<Func(ArgType0,ArgType1,ArgType2)> {
|
||||
enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
|
||||
typedef typename ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, FunctorType>::type type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if EIGEN_HAS_STD_INVOKE_RESULT
|
||||
template<typename F, typename... ArgTypes>
|
||||
struct invoke_result {
|
||||
typedef typename std::invoke_result<F, ArgTypes...>::type type1;
|
||||
typedef typename remove_all<type1>::type type;
|
||||
};
|
||||
#elif EIGEN_HAS_CXX11
|
||||
template<typename F, typename... ArgTypes>
|
||||
struct invoke_result {
|
||||
typedef typename result_of<F(ArgTypes...)>::type type1;
|
||||
typedef typename remove_all<type1>::type type;
|
||||
};
|
||||
#else
|
||||
template<typename F, typename ArgType0 = void, typename ArgType1 = void, typename ArgType2 = void>
|
||||
struct invoke_result {
|
||||
typedef typename result_of<F(ArgType0, ArgType1, ArgType2)>::type type1;
|
||||
typedef typename remove_all<type1>::type type;
|
||||
};
|
||||
|
||||
template<typename F>
|
||||
struct invoke_result<F, void, void, void> {
|
||||
typedef typename result_of<F()>::type type1;
|
||||
typedef typename remove_all<type1>::type type;
|
||||
};
|
||||
|
||||
template<typename F, typename ArgType0>
|
||||
struct invoke_result<F, ArgType0, void, void> {
|
||||
typedef typename result_of<F(ArgType0)>::type type1;
|
||||
typedef typename remove_all<type1>::type type;
|
||||
};
|
||||
|
||||
template<typename F, typename ArgType0, typename ArgType1>
|
||||
struct invoke_result<F, ArgType0, ArgType1, void> {
|
||||
typedef typename result_of<F(ArgType0, ArgType1)>::type type1;
|
||||
typedef typename remove_all<type1>::type type;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct meta_yes { char a[1]; };
|
||||
@@ -684,7 +761,7 @@ template<typename T> EIGEN_DEVICE_FUNC void swap(T &a, T &b) { T tmp = b; b =
|
||||
template<typename T> EIGEN_STRONG_INLINE void swap(T &a, T &b) { std::swap(a,b); }
|
||||
#endif
|
||||
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE) && !EIGEN_HAS_CXX11
|
||||
using internal::device::numeric_limits;
|
||||
#else
|
||||
using std::numeric_limits;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#ifndef EIGEN_STATIC_ASSERT
|
||||
#ifndef EIGEN_NO_STATIC_ASSERT
|
||||
|
||||
#if EIGEN_MAX_CPP_VER>=11 && (__has_feature(cxx_static_assert) || (defined(__cplusplus) && __cplusplus >= 201103L) || (EIGEN_COMP_MSVC >= 1600))
|
||||
#if EIGEN_MAX_CPP_VER>=11 && (__has_feature(cxx_static_assert) || (EIGEN_COMP_CXXVER >= 11) || (EIGEN_COMP_MSVC >= 1600))
|
||||
|
||||
// if native static_assert is enabled, let's use it
|
||||
#define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG);
|
||||
|
||||
@@ -65,7 +65,7 @@ class ValueExpr<internal::FixedInt<N> > {
|
||||
public:
|
||||
ValueExpr() {}
|
||||
template<typename T>
|
||||
Index eval_impl(const T&) const { return N; }
|
||||
EIGEN_CONSTEXPR Index eval_impl(const T&) const { return N; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -129,11 +129,14 @@ struct promote_index_type
|
||||
template<typename T, int Value> class variable_if_dynamic
|
||||
{
|
||||
public:
|
||||
EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamic)
|
||||
EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(variable_if_dynamic)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamic(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
|
||||
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T value() { return T(Value); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE operator T() const { return T(Value); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T) {}
|
||||
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
T value() { return T(Value); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
operator T() const { return T(Value); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
void setValue(T) const {}
|
||||
};
|
||||
|
||||
template<typename T> class variable_if_dynamic<T, Dynamic>
|
||||
@@ -154,8 +157,10 @@ template<typename T, int Value> class variable_if_dynamicindex
|
||||
public:
|
||||
EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamicindex)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamicindex(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
|
||||
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T value() { return T(Value); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T) {}
|
||||
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
T value() { return T(Value); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
void setValue(T) {}
|
||||
};
|
||||
|
||||
template<typename T> class variable_if_dynamicindex<T, DynamicIndex>
|
||||
@@ -428,7 +433,7 @@ struct ref_selector
|
||||
T const&,
|
||||
const T
|
||||
>::type type;
|
||||
|
||||
|
||||
typedef typename conditional<
|
||||
bool(traits<T>::Flags & NestByRefBit),
|
||||
T &,
|
||||
@@ -614,7 +619,7 @@ struct plain_row_type
|
||||
typedef typename conditional<
|
||||
is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
|
||||
MatrixRowType,
|
||||
ArrayRowType
|
||||
ArrayRowType
|
||||
>::type type;
|
||||
};
|
||||
|
||||
@@ -629,7 +634,7 @@ struct plain_col_type
|
||||
typedef typename conditional<
|
||||
is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
|
||||
MatrixColType,
|
||||
ArrayColType
|
||||
ArrayColType
|
||||
>::type type;
|
||||
};
|
||||
|
||||
@@ -645,7 +650,7 @@ struct plain_diag_type
|
||||
typedef typename conditional<
|
||||
is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
|
||||
MatrixDiagType,
|
||||
ArrayDiagType
|
||||
ArrayDiagType
|
||||
>::type type;
|
||||
};
|
||||
|
||||
@@ -761,7 +766,7 @@ std::string demangle_flags(int f)
|
||||
if(f&DirectAccessBit) res += " | Direct";
|
||||
if(f&NestByRefBit) res += " | NestByRef";
|
||||
if(f&NoPreferredStorageOrderBit) res += " | NoPreferredStorageOrderBit";
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
@@ -858,7 +863,7 @@ struct ScalarBinaryOpTraits<void,void,BinaryOp>
|
||||
#define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \
|
||||
EIGEN_STATIC_ASSERT((Eigen::internal::has_ReturnType<ScalarBinaryOpTraits<LHS, RHS,BINOP> >::value), \
|
||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_XPRHELPER_H
|
||||
|
||||
@@ -44,10 +44,14 @@ ComputationInfo computeFromTridiagonal_impl(DiagType& diag, SubDiagType& subdiag
|
||||
* \f$ v \f$ such that \f$ Av = \lambda v \f$. The eigenvalues of a
|
||||
* selfadjoint matrix are always real. If \f$ D \f$ is a diagonal matrix with
|
||||
* the eigenvalues on the diagonal, and \f$ V \f$ is a matrix with the
|
||||
* eigenvectors as its columns, then \f$ A = V D V^{-1} \f$ (for selfadjoint
|
||||
* matrices, the matrix \f$ V \f$ is always invertible). This is called the
|
||||
* eigenvectors as its columns, then \f$ A = V D V^{-1} \f$. This is called the
|
||||
* eigendecomposition.
|
||||
*
|
||||
* For a selfadjoint matrix, \f$ V \f$ is unitary, meaning its inverse is equal
|
||||
* to its adjoint, \f$ V^{-1} = V^{\dagger} \f$. If \f$ A \f$ is real, then
|
||||
* \f$ V \f$ is also real and therefore orthogonal, meaning its inverse is
|
||||
* equal to its transpose, \f$ V^{-1} = V^T \f$.
|
||||
*
|
||||
* The algorithm exploits the fact that the matrix is selfadjoint, making it
|
||||
* faster and more accurate than the general purpose eigenvalue algorithms
|
||||
* implemented in EigenSolver and ComplexEigenSolver.
|
||||
@@ -256,6 +260,11 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
|
||||
* matrix \f$ A \f$, then the matrix returned by this function is the
|
||||
* matrix \f$ V \f$ in the eigendecomposition \f$ A = V D V^{-1} \f$.
|
||||
*
|
||||
* For a selfadjoint matrix, \f$ V \f$ is unitary, meaning its inverse is equal
|
||||
* to its adjoint, \f$ V^{-1} = V^{\dagger} \f$. If \f$ A \f$ is real, then
|
||||
* \f$ V \f$ is also real and therefore orthogonal, meaning its inverse is
|
||||
* equal to its transpose, \f$ V^{-1} = V^T \f$.
|
||||
*
|
||||
* Example: \include SelfAdjointEigenSolver_eigenvectors.cpp
|
||||
* Output: \verbinclude SelfAdjointEigenSolver_eigenvectors.out
|
||||
*
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
#ifndef EIGEN_TRIDIAGONALIZATION_H
|
||||
#define EIGEN_TRIDIAGONALIZATION_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
|
||||
template<typename MatrixType> struct TridiagonalizationMatrixTReturnType;
|
||||
template<typename MatrixType>
|
||||
struct traits<TridiagonalizationMatrixTReturnType<MatrixType> >
|
||||
@@ -354,7 +354,7 @@ void tridiagonalization_inplace(MatrixType& matA, CoeffVectorType& hCoeffs)
|
||||
Index n = matA.rows();
|
||||
eigen_assert(n==matA.cols());
|
||||
eigen_assert(n==hCoeffs.size()+1 || n==1);
|
||||
|
||||
|
||||
for (Index i = 0; i<n-1; ++i)
|
||||
{
|
||||
Index remainingSize = n-i-1;
|
||||
@@ -547,8 +547,8 @@ template<typename MatrixType> struct TridiagonalizationMatrixTReturnType
|
||||
result.template diagonal<-1>() = m_matrix.template diagonal<-1>();
|
||||
}
|
||||
|
||||
Index rows() const { return m_matrix.rows(); }
|
||||
Index cols() const { return m_matrix.cols(); }
|
||||
EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
|
||||
EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
|
||||
|
||||
protected:
|
||||
typename MatrixType::Nested m_matrix;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#ifndef EIGEN_HOMOGENEOUS_H
|
||||
#define EIGEN_HOMOGENEOUS_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
/** \geometry_module \ingroup Geometry_Module
|
||||
*
|
||||
@@ -72,9 +72,11 @@ template<typename MatrixType,int _Direction> class Homogeneous
|
||||
: m_matrix(matrix)
|
||||
{}
|
||||
|
||||
EIGEN_DEVICE_FUNC inline Index rows() const { return m_matrix.rows() + (int(Direction)==Vertical ? 1 : 0); }
|
||||
EIGEN_DEVICE_FUNC inline Index cols() const { return m_matrix.cols() + (int(Direction)==Horizontal ? 1 : 0); }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index rows() const EIGEN_NOEXCEPT { return m_matrix.rows() + (int(Direction)==Vertical ? 1 : 0); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols() + (int(Direction)==Horizontal ? 1 : 0); }
|
||||
|
||||
EIGEN_DEVICE_FUNC const NestedExpression& nestedExpression() const { return m_matrix; }
|
||||
|
||||
template<typename Rhs>
|
||||
@@ -262,8 +264,10 @@ struct homogeneous_left_product_impl<Homogeneous<MatrixType,Vertical>,Lhs>
|
||||
m_rhs(rhs)
|
||||
{}
|
||||
|
||||
EIGEN_DEVICE_FUNC inline Index rows() const { return m_lhs.rows(); }
|
||||
EIGEN_DEVICE_FUNC inline Index cols() const { return m_rhs.cols(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index rows() const EIGEN_NOEXCEPT { return m_lhs.rows(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index cols() const EIGEN_NOEXCEPT { return m_rhs.cols(); }
|
||||
|
||||
template<typename Dest> EIGEN_DEVICE_FUNC void evalTo(Dest& dst) const
|
||||
{
|
||||
@@ -300,8 +304,8 @@ struct homogeneous_right_product_impl<Homogeneous<MatrixType,Horizontal>,Rhs>
|
||||
: m_lhs(lhs), m_rhs(rhs)
|
||||
{}
|
||||
|
||||
EIGEN_DEVICE_FUNC inline Index rows() const { return m_lhs.rows(); }
|
||||
EIGEN_DEVICE_FUNC inline Index cols() const { return m_rhs.cols(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index rows() const EIGEN_NOEXCEPT { return m_lhs.rows(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index cols() const EIGEN_NOEXCEPT { return m_rhs.cols(); }
|
||||
|
||||
template<typename Dest> EIGEN_DEVICE_FUNC void evalTo(Dest& dst) const
|
||||
{
|
||||
@@ -322,7 +326,7 @@ template<typename ArgType,int Direction>
|
||||
struct evaluator_traits<Homogeneous<ArgType,Direction> >
|
||||
{
|
||||
typedef typename storage_kind_to_evaluator_kind<typename ArgType::StorageKind>::Kind Kind;
|
||||
typedef HomogeneousShape Shape;
|
||||
typedef HomogeneousShape Shape;
|
||||
};
|
||||
|
||||
template<> struct AssignmentKind<DenseShape,HomogeneousShape> { typedef Dense2Dense Kind; };
|
||||
@@ -414,7 +418,7 @@ struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, Homogeneous
|
||||
typedef typename helper::ConstantBlock ConstantBlock;
|
||||
typedef typename helper::Xpr RefactoredXpr;
|
||||
typedef evaluator<RefactoredXpr> Base;
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr)
|
||||
: Base( xpr.lhs().nestedExpression() .lazyProduct( xpr.rhs().template topRows<helper::Dim>(xpr.lhs().nestedExpression().cols()) )
|
||||
+ ConstantBlock(xpr.rhs().row(xpr.rhs().rows()-1),xpr.lhs().rows(), 1) )
|
||||
@@ -467,7 +471,7 @@ struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape,
|
||||
typedef typename helper::ConstantBlock ConstantBlock;
|
||||
typedef typename helper::Xpr RefactoredXpr;
|
||||
typedef evaluator<RefactoredXpr> Base;
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr)
|
||||
: Base( xpr.lhs().template leftCols<helper::Dim>(xpr.rhs().nestedExpression().rows()) .lazyProduct( xpr.rhs().nestedExpression() )
|
||||
+ ConstantBlock(xpr.lhs().col(xpr.lhs().cols()-1),1,xpr.rhs().cols()) )
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#ifndef EIGEN_TRANSFORM_H
|
||||
#define EIGEN_TRANSFORM_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
@@ -47,7 +47,7 @@ struct transform_left_product_impl;
|
||||
|
||||
template< typename Lhs,
|
||||
typename Rhs,
|
||||
bool AnyProjective =
|
||||
bool AnyProjective =
|
||||
transform_traits<Lhs>::IsProjective ||
|
||||
transform_traits<Rhs>::IsProjective>
|
||||
struct transform_transform_product_impl;
|
||||
@@ -223,9 +223,9 @@ public:
|
||||
/** type of the matrix used to represent the linear part of the transformation */
|
||||
typedef Matrix<Scalar,Dim,Dim,Options> LinearMatrixType;
|
||||
/** type of read/write reference to the linear part of the transformation */
|
||||
typedef Block<MatrixType,Dim,Dim,int(Mode)==(AffineCompact) && (Options&RowMajor)==0> LinearPart;
|
||||
typedef Block<MatrixType,Dim,Dim,int(Mode)==(AffineCompact) && (int(Options)&RowMajor)==0> LinearPart;
|
||||
/** type of read reference to the linear part of the transformation */
|
||||
typedef const Block<ConstMatrixType,Dim,Dim,int(Mode)==(AffineCompact) && (Options&RowMajor)==0> ConstLinearPart;
|
||||
typedef const Block<ConstMatrixType,Dim,Dim,int(Mode)==(AffineCompact) && (int(Options)&RowMajor)==0> ConstLinearPart;
|
||||
/** type of read/write reference to the affine part of the transformation */
|
||||
typedef typename internal::conditional<int(Mode)==int(AffineCompact),
|
||||
MatrixType&,
|
||||
@@ -242,7 +242,7 @@ public:
|
||||
typedef const Block<ConstMatrixType,Dim,1,!(internal::traits<MatrixType>::Flags & RowMajorBit)> ConstTranslationPart;
|
||||
/** corresponding translation type */
|
||||
typedef Translation<Scalar,Dim> TranslationType;
|
||||
|
||||
|
||||
// this intermediate enum is needed to avoid an ICE with gcc 3.4 and 4.0
|
||||
enum { TransformTimeDiagonalMode = ((Mode==int(Isometry))?Affine:int(Mode)) };
|
||||
/** The return type of the product between a diagonal matrix and a transform */
|
||||
@@ -302,7 +302,7 @@ public:
|
||||
internal::transform_construct_from_matrix<OtherDerived,Mode,Options,Dim,HDim>::run(this, other.derived());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template<int OtherOptions>
|
||||
EIGEN_DEVICE_FUNC inline Transform(const Transform<Scalar,Dim,Mode,OtherOptions>& other)
|
||||
{
|
||||
@@ -374,9 +374,9 @@ public:
|
||||
inline Transform& operator=(const QTransform& other);
|
||||
inline QTransform toQTransform(void) const;
|
||||
#endif
|
||||
|
||||
EIGEN_DEVICE_FUNC Index rows() const { return int(Mode)==int(Projective) ? m_matrix.cols() : (m_matrix.cols()-1); }
|
||||
EIGEN_DEVICE_FUNC Index cols() const { return m_matrix.cols(); }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return int(Mode)==int(Projective) ? m_matrix.cols() : (m_matrix.cols()-1); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
|
||||
|
||||
/** shortcut for m_matrix(row,col);
|
||||
* \sa MatrixBase::operator(Index,Index) const */
|
||||
@@ -450,7 +450,7 @@ public:
|
||||
/** \returns The product expression of a transform \a a times a diagonal matrix \a b
|
||||
*
|
||||
* The rhs diagonal matrix is interpreted as an affine scaling transformation. The
|
||||
* product results in a Transform of the same type (mode) as the lhs only if the lhs
|
||||
* product results in a Transform of the same type (mode) as the lhs only if the lhs
|
||||
* mode is no isometry. In that case, the returned transform is an affinity.
|
||||
*/
|
||||
template<typename DiagonalDerived>
|
||||
@@ -465,7 +465,7 @@ public:
|
||||
/** \returns The product expression of a diagonal matrix \a a times a transform \a b
|
||||
*
|
||||
* The lhs diagonal matrix is interpreted as an affine scaling transformation. The
|
||||
* product results in a Transform of the same type (mode) as the lhs only if the lhs
|
||||
* product results in a Transform of the same type (mode) as the lhs only if the lhs
|
||||
* mode is no isometry. In that case, the returned transform is an affinity.
|
||||
*/
|
||||
template<typename DiagonalDerived>
|
||||
@@ -488,7 +488,7 @@ public:
|
||||
{
|
||||
return internal::transform_transform_product_impl<Transform,Transform>::run(*this,other);
|
||||
}
|
||||
|
||||
|
||||
#if EIGEN_COMP_ICC
|
||||
private:
|
||||
// this intermediate structure permits to workaround a bug in ICC 11:
|
||||
@@ -497,13 +497,13 @@ private:
|
||||
// (the meaning of a name may have changed since the template declaration -- the type of the template is:
|
||||
// "Eigen::internal::transform_transform_product_impl<Eigen::Transform<double, 3, 32, 0>,
|
||||
// Eigen::Transform<double, 3, Mode, Options>, <expression>>::ResultType (const Eigen::Transform<double, 3, Mode, Options> &) const")
|
||||
//
|
||||
//
|
||||
template<int OtherMode,int OtherOptions> struct icc_11_workaround
|
||||
{
|
||||
typedef internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> > ProductType;
|
||||
typedef typename ProductType::ResultType ResultType;
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
/** Concatenates two different transformations */
|
||||
template<int OtherMode,int OtherOptions>
|
||||
@@ -536,7 +536,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Transform& scale(const MatrixBase<OtherDerived> &other);
|
||||
|
||||
template<typename OtherDerived>
|
||||
@@ -566,18 +566,18 @@ public:
|
||||
EIGEN_DEVICE_FUNC Transform& preshear(const Scalar& sx, const Scalar& sy);
|
||||
|
||||
EIGEN_DEVICE_FUNC inline Transform& operator=(const TranslationType& t);
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Transform& operator*=(const TranslationType& t) { return translate(t.vector()); }
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC inline Transform operator*(const TranslationType& t) const;
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Transform& operator=(const UniformScaling<Scalar>& t);
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Transform& operator*=(const UniformScaling<Scalar>& s) { return scale(s.factor()); }
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline TransformTimeDiagonalReturnType operator*(const UniformScaling<Scalar>& s) const
|
||||
{
|
||||
@@ -680,7 +680,7 @@ public:
|
||||
#ifdef EIGEN_TRANSFORM_PLUGIN
|
||||
#include EIGEN_TRANSFORM_PLUGIN
|
||||
#endif
|
||||
|
||||
|
||||
protected:
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void check_template_params()
|
||||
@@ -1048,7 +1048,7 @@ template<int Mode> struct transform_rotation_impl {
|
||||
EIGEN_DEVICE_FUNC static inline
|
||||
const typename TransformType::LinearMatrixType run(const TransformType& t)
|
||||
{
|
||||
typedef typename TransformType::LinearMatrixType LinearMatrixType;
|
||||
typedef typename TransformType::LinearMatrixType LinearMatrixType;
|
||||
LinearMatrixType result;
|
||||
t.computeRotationScaling(&result, (LinearMatrixType*)0);
|
||||
return result;
|
||||
@@ -1177,7 +1177,7 @@ struct transform_make_affine<AffineCompact>
|
||||
{
|
||||
template<typename MatrixType> EIGEN_DEVICE_FUNC static void run(MatrixType &) { }
|
||||
};
|
||||
|
||||
|
||||
// selector needed to avoid taking the inverse of a 3x4 matrix
|
||||
template<typename TransformType, int Mode=TransformType::Mode>
|
||||
struct projective_transform_inverse
|
||||
@@ -1318,8 +1318,8 @@ struct transform_construct_from_matrix<Other, AffineCompact,Options,Dim,HDim, HD
|
||||
template<int LhsMode,int RhsMode>
|
||||
struct transform_product_result
|
||||
{
|
||||
enum
|
||||
{
|
||||
enum
|
||||
{
|
||||
Mode =
|
||||
(LhsMode == (int)Projective || RhsMode == (int)Projective ) ? Projective :
|
||||
(LhsMode == (int)Affine || RhsMode == (int)Affine ) ? Affine :
|
||||
@@ -1342,8 +1342,8 @@ struct transform_right_product_impl< TransformType, MatrixType, 0, RhsCols>
|
||||
template< typename TransformType, typename MatrixType, int RhsCols>
|
||||
struct transform_right_product_impl< TransformType, MatrixType, 1, RhsCols>
|
||||
{
|
||||
enum {
|
||||
Dim = TransformType::Dim,
|
||||
enum {
|
||||
Dim = TransformType::Dim,
|
||||
HDim = TransformType::HDim,
|
||||
OtherRows = MatrixType::RowsAtCompileTime,
|
||||
OtherCols = MatrixType::ColsAtCompileTime
|
||||
@@ -1360,7 +1360,7 @@ struct transform_right_product_impl< TransformType, MatrixType, 1, RhsCols>
|
||||
ResultType res(other.rows(),other.cols());
|
||||
TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() = T.affine() * other;
|
||||
res.row(OtherRows-1) = other.row(OtherRows-1);
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
};
|
||||
@@ -1368,8 +1368,8 @@ struct transform_right_product_impl< TransformType, MatrixType, 1, RhsCols>
|
||||
template< typename TransformType, typename MatrixType, int RhsCols>
|
||||
struct transform_right_product_impl< TransformType, MatrixType, 2, RhsCols>
|
||||
{
|
||||
enum {
|
||||
Dim = TransformType::Dim,
|
||||
enum {
|
||||
Dim = TransformType::Dim,
|
||||
HDim = TransformType::HDim,
|
||||
OtherRows = MatrixType::RowsAtCompileTime,
|
||||
OtherCols = MatrixType::ColsAtCompileTime
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#ifndef EIGEN_HOUSEHOLDER_SEQUENCE_H
|
||||
#define EIGEN_HOUSEHOLDER_SEQUENCE_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
/** \ingroup Householder_Module
|
||||
* \householder_module
|
||||
@@ -34,8 +34,8 @@ namespace Eigen {
|
||||
* form \f$ H = \prod_{i=0}^{n-1} H_i \f$ where the i-th Householder reflection is \f$ H_i = I - h_i v_i
|
||||
* v_i^* \f$. The i-th Householder coefficient \f$ h_i \f$ is a scalar and the i-th Householder vector \f$
|
||||
* v_i \f$ is a vector of the form
|
||||
* \f[
|
||||
* v_i = [\underbrace{0, \ldots, 0}_{i-1\mbox{ zeros}}, 1, \underbrace{*, \ldots,*}_{n-i\mbox{ arbitrary entries}} ].
|
||||
* \f[
|
||||
* v_i = [\underbrace{0, \ldots, 0}_{i-1\mbox{ zeros}}, 1, \underbrace{*, \ldots,*}_{n-i\mbox{ arbitrary entries}} ].
|
||||
* \f]
|
||||
* The last \f$ n-i \f$ entries of \f$ v_i \f$ are called the essential part of the Householder vector.
|
||||
*
|
||||
@@ -120,7 +120,7 @@ template<typename VectorsType, typename CoeffsType, int Side> class HouseholderS
|
||||
: public EigenBase<HouseholderSequence<VectorsType,CoeffsType,Side> >
|
||||
{
|
||||
typedef typename internal::hseq_side_dependent_impl<VectorsType,CoeffsType,Side>::EssentialVectorType EssentialVectorType;
|
||||
|
||||
|
||||
public:
|
||||
enum {
|
||||
RowsAtCompileTime = internal::traits<HouseholderSequence>::RowsAtCompileTime,
|
||||
@@ -198,18 +198,18 @@ template<typename VectorsType, typename CoeffsType, int Side> class HouseholderS
|
||||
}
|
||||
|
||||
/** \brief Number of rows of transformation viewed as a matrix.
|
||||
* \returns Number of rows
|
||||
* \returns Number of rows
|
||||
* \details This equals the dimension of the space that the transformation acts on.
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
Index rows() const { return Side==OnTheLeft ? m_vectors.rows() : m_vectors.cols(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
Index rows() const EIGEN_NOEXCEPT { return Side==OnTheLeft ? m_vectors.rows() : m_vectors.cols(); }
|
||||
|
||||
/** \brief Number of columns of transformation viewed as a matrix.
|
||||
* \returns Number of columns
|
||||
* \details This equals the dimension of the space that the transformation acts on.
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
Index cols() const { return rows(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
Index cols() const EIGEN_NOEXCEPT { return rows(); }
|
||||
|
||||
/** \brief Essential part of a Householder vector.
|
||||
* \param[in] k Index of Householder reflection
|
||||
@@ -217,8 +217,8 @@ template<typename VectorsType, typename CoeffsType, int Side> class HouseholderS
|
||||
*
|
||||
* This function returns the essential part of the Householder vector \f$ v_i \f$. This is a vector of
|
||||
* length \f$ n-i \f$ containing the last \f$ n-i \f$ entries of the vector
|
||||
* \f[
|
||||
* v_i = [\underbrace{0, \ldots, 0}_{i-1\mbox{ zeros}}, 1, \underbrace{*, \ldots,*}_{n-i\mbox{ arbitrary entries}} ].
|
||||
* \f[
|
||||
* v_i = [\underbrace{0, \ldots, 0}_{i-1\mbox{ zeros}}, 1, \underbrace{*, \ldots,*}_{n-i\mbox{ arbitrary entries}} ].
|
||||
* \f]
|
||||
* The index \f$ i \f$ equals \p k + shift(), corresponding to the k-th column of the matrix \p v
|
||||
* passed to the constructor.
|
||||
@@ -381,7 +381,7 @@ template<typename VectorsType, typename CoeffsType, int Side> class HouseholderS
|
||||
Index k = m_reverse ? i : (std::max)(Index(0),end-blockSize);
|
||||
Index bs = end-k;
|
||||
Index start = k + m_shift;
|
||||
|
||||
|
||||
typedef Block<typename internal::remove_all<VectorsType>::type,Dynamic,Dynamic> SubVectorsType;
|
||||
SubVectorsType sub_vecs1(m_vectors.const_cast_derived(), Side==OnTheRight ? k : start,
|
||||
Side==OnTheRight ? start : k,
|
||||
@@ -519,7 +519,7 @@ typename internal::matrix_type_times_scalar_type<typename VectorsType::Scalar,Ot
|
||||
}
|
||||
|
||||
/** \ingroup Householder_Module \householder_module
|
||||
* \brief Convenience function for constructing a Householder sequence.
|
||||
* \brief Convenience function for constructing a Householder sequence.
|
||||
* \returns A HouseholderSequence constructed from the specified arguments.
|
||||
*/
|
||||
template<typename VectorsType, typename CoeffsType>
|
||||
@@ -529,7 +529,7 @@ HouseholderSequence<VectorsType,CoeffsType> householderSequence(const VectorsTyp
|
||||
}
|
||||
|
||||
/** \ingroup Householder_Module \householder_module
|
||||
* \brief Convenience function for constructing a Householder sequence.
|
||||
* \brief Convenience function for constructing a Householder sequence.
|
||||
* \returns A HouseholderSequence constructed from the specified arguments.
|
||||
* \details This function differs from householderSequence() in that the template argument \p OnTheSide of
|
||||
* the constructed HouseholderSequence is set to OnTheRight, instead of the default OnTheLeft.
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#ifndef EIGEN_BASIC_PRECONDITIONERS_H
|
||||
#define EIGEN_BASIC_PRECONDITIONERS_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
/** \ingroup IterativeLinearSolvers_Module
|
||||
* \brief A preconditioner based on the digonal entries
|
||||
@@ -52,15 +52,15 @@ class DiagonalPreconditioner
|
||||
compute(mat);
|
||||
}
|
||||
|
||||
Index rows() const { return m_invdiag.size(); }
|
||||
Index cols() const { return m_invdiag.size(); }
|
||||
|
||||
EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_invdiag.size(); }
|
||||
EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_invdiag.size(); }
|
||||
|
||||
template<typename MatType>
|
||||
DiagonalPreconditioner& analyzePattern(const MatType& )
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template<typename MatType>
|
||||
DiagonalPreconditioner& factorize(const MatType& mat)
|
||||
{
|
||||
@@ -77,7 +77,7 @@ class DiagonalPreconditioner
|
||||
m_isInitialized = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template<typename MatType>
|
||||
DiagonalPreconditioner& compute(const MatType& mat)
|
||||
{
|
||||
@@ -99,7 +99,7 @@ class DiagonalPreconditioner
|
||||
&& "DiagonalPreconditioner::solve(): invalid number of rows of the right hand side matrix b");
|
||||
return Solve<DiagonalPreconditioner, Rhs>(*this, b.derived());
|
||||
}
|
||||
|
||||
|
||||
ComputationInfo info() { return Success; }
|
||||
|
||||
protected:
|
||||
@@ -121,7 +121,7 @@ class DiagonalPreconditioner
|
||||
* \implsparsesolverconcept
|
||||
*
|
||||
* The diagonal entries are pre-inverted and stored into a dense vector.
|
||||
*
|
||||
*
|
||||
* \sa class LeastSquaresConjugateGradient, class DiagonalPreconditioner
|
||||
*/
|
||||
template <typename _Scalar>
|
||||
@@ -146,7 +146,7 @@ class LeastSquareDiagonalPreconditioner : public DiagonalPreconditioner<_Scalar>
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template<typename MatType>
|
||||
LeastSquareDiagonalPreconditioner& factorize(const MatType& mat)
|
||||
{
|
||||
@@ -178,13 +178,13 @@ class LeastSquareDiagonalPreconditioner : public DiagonalPreconditioner<_Scalar>
|
||||
Base::m_isInitialized = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template<typename MatType>
|
||||
LeastSquareDiagonalPreconditioner& compute(const MatType& mat)
|
||||
{
|
||||
return factorize(mat);
|
||||
}
|
||||
|
||||
|
||||
ComputationInfo info() { return Success; }
|
||||
|
||||
protected:
|
||||
@@ -205,19 +205,19 @@ class IdentityPreconditioner
|
||||
|
||||
template<typename MatrixType>
|
||||
explicit IdentityPreconditioner(const MatrixType& ) {}
|
||||
|
||||
|
||||
template<typename MatrixType>
|
||||
IdentityPreconditioner& analyzePattern(const MatrixType& ) { return *this; }
|
||||
|
||||
|
||||
template<typename MatrixType>
|
||||
IdentityPreconditioner& factorize(const MatrixType& ) { return *this; }
|
||||
|
||||
template<typename MatrixType>
|
||||
IdentityPreconditioner& compute(const MatrixType& ) { return *this; }
|
||||
|
||||
|
||||
template<typename Rhs>
|
||||
inline const Rhs& solve(const Rhs& b) const { return b; }
|
||||
|
||||
|
||||
ComputationInfo info() { return Success; }
|
||||
};
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
namespace Eigen {
|
||||
/**
|
||||
namespace Eigen {
|
||||
/**
|
||||
* \brief Modified Incomplete Cholesky with dual threshold
|
||||
*
|
||||
* References : C-J. Lin and J. J. Moré, Incomplete Cholesky Factorizations with
|
||||
@@ -48,15 +48,15 @@ class IncompleteCholesky : public SparseSolverBase<IncompleteCholesky<Scalar,_Up
|
||||
typedef SparseSolverBase<IncompleteCholesky<Scalar,_UpLo,_OrderingType> > Base;
|
||||
using Base::m_isInitialized;
|
||||
public:
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
typedef _OrderingType OrderingType;
|
||||
typedef typename OrderingType::PermutationType PermutationType;
|
||||
typedef typename PermutationType::StorageIndex StorageIndex;
|
||||
typedef typename PermutationType::StorageIndex StorageIndex;
|
||||
typedef SparseMatrix<Scalar,ColMajor,StorageIndex> FactorType;
|
||||
typedef Matrix<Scalar,Dynamic,1> VectorSx;
|
||||
typedef Matrix<RealScalar,Dynamic,1> VectorRx;
|
||||
typedef Matrix<StorageIndex,Dynamic, 1> VectorIx;
|
||||
typedef std::vector<std::list<StorageIndex> > VectorList;
|
||||
typedef std::vector<std::list<StorageIndex> > VectorList;
|
||||
enum { UpLo = _UpLo };
|
||||
enum {
|
||||
ColsAtCompileTime = Dynamic,
|
||||
@@ -71,7 +71,7 @@ class IncompleteCholesky : public SparseSolverBase<IncompleteCholesky<Scalar,_Up
|
||||
* \sa IncompleteCholesky(const MatrixType&)
|
||||
*/
|
||||
IncompleteCholesky() : m_initialShift(1e-3),m_analysisIsOk(false),m_factorizationIsOk(false) {}
|
||||
|
||||
|
||||
/** Constructor computing the incomplete factorization for the given matrix \a matrix.
|
||||
*/
|
||||
template<typename MatrixType>
|
||||
@@ -79,13 +79,13 @@ class IncompleteCholesky : public SparseSolverBase<IncompleteCholesky<Scalar,_Up
|
||||
{
|
||||
compute(matrix);
|
||||
}
|
||||
|
||||
|
||||
/** \returns number of rows of the factored matrix */
|
||||
Index rows() const { return m_L.rows(); }
|
||||
|
||||
EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_L.rows(); }
|
||||
|
||||
/** \returns number of columns of the factored matrix */
|
||||
Index cols() const { return m_L.cols(); }
|
||||
|
||||
EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_L.cols(); }
|
||||
|
||||
|
||||
/** \brief Reports whether previous computation was successful.
|
||||
*
|
||||
@@ -100,19 +100,19 @@ class IncompleteCholesky : public SparseSolverBase<IncompleteCholesky<Scalar,_Up
|
||||
eigen_assert(m_isInitialized && "IncompleteCholesky is not initialized.");
|
||||
return m_info;
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set the initial shift parameter \f$ \sigma \f$.
|
||||
*/
|
||||
void setInitialShift(RealScalar shift) { m_initialShift = shift; }
|
||||
|
||||
|
||||
/** \brief Computes the fill reducing permutation vector using the sparsity pattern of \a mat
|
||||
*/
|
||||
template<typename MatrixType>
|
||||
void analyzePattern(const MatrixType& mat)
|
||||
{
|
||||
OrderingType ord;
|
||||
OrderingType ord;
|
||||
PermutationType pinv;
|
||||
ord(mat.template selfadjointView<UpLo>(), pinv);
|
||||
ord(mat.template selfadjointView<UpLo>(), pinv);
|
||||
if(pinv.size()>0) m_perm = pinv.inverse();
|
||||
else m_perm.resize(0);
|
||||
m_L.resize(mat.rows(), mat.cols());
|
||||
@@ -120,7 +120,7 @@ class IncompleteCholesky : public SparseSolverBase<IncompleteCholesky<Scalar,_Up
|
||||
m_isInitialized = true;
|
||||
m_info = Success;
|
||||
}
|
||||
|
||||
|
||||
/** \brief Performs the numerical factorization of the input matrix \a mat
|
||||
*
|
||||
* The method analyzePattern() or compute() must have been called beforehand
|
||||
@@ -130,7 +130,7 @@ class IncompleteCholesky : public SparseSolverBase<IncompleteCholesky<Scalar,_Up
|
||||
*/
|
||||
template<typename MatrixType>
|
||||
void factorize(const MatrixType& mat);
|
||||
|
||||
|
||||
/** Computes or re-computes the incomplete Cholesky factorization of the input matrix \a mat
|
||||
*
|
||||
* It is a shortcut for a sequential call to the analyzePattern() and factorize() methods.
|
||||
@@ -143,7 +143,7 @@ class IncompleteCholesky : public SparseSolverBase<IncompleteCholesky<Scalar,_Up
|
||||
analyzePattern(mat);
|
||||
factorize(mat);
|
||||
}
|
||||
|
||||
|
||||
// internal
|
||||
template<typename Rhs, typename Dest>
|
||||
void _solve_impl(const Rhs& b, Dest& x) const
|
||||
@@ -170,16 +170,16 @@ class IncompleteCholesky : public SparseSolverBase<IncompleteCholesky<Scalar,_Up
|
||||
|
||||
protected:
|
||||
FactorType m_L; // The lower part stored in CSC
|
||||
VectorRx m_scale; // The vector for scaling the matrix
|
||||
VectorRx m_scale; // The vector for scaling the matrix
|
||||
RealScalar m_initialShift; // The initial shift parameter
|
||||
bool m_analysisIsOk;
|
||||
bool m_factorizationIsOk;
|
||||
bool m_analysisIsOk;
|
||||
bool m_factorizationIsOk;
|
||||
ComputationInfo m_info;
|
||||
PermutationType m_perm;
|
||||
PermutationType m_perm;
|
||||
|
||||
private:
|
||||
inline void updateList(Ref<const VectorIx> colPtr, Ref<VectorIx> rowIdx, Ref<VectorSx> vals, const Index& col, const Index& jk, VectorIx& firstElt, VectorList& listCol);
|
||||
};
|
||||
inline void updateList(Ref<const VectorIx> colPtr, Ref<VectorIx> rowIdx, Ref<VectorSx> vals, const Index& col, const Index& jk, VectorIx& firstElt, VectorList& listCol);
|
||||
};
|
||||
|
||||
// Based on the following paper:
|
||||
// C-J. Lin and J. J. Moré, Incomplete Cholesky Factorizations with
|
||||
@@ -190,10 +190,10 @@ template<typename _MatrixType>
|
||||
void IncompleteCholesky<Scalar,_UpLo, OrderingType>::factorize(const _MatrixType& mat)
|
||||
{
|
||||
using std::sqrt;
|
||||
eigen_assert(m_analysisIsOk && "analyzePattern() should be called first");
|
||||
|
||||
eigen_assert(m_analysisIsOk && "analyzePattern() should be called first");
|
||||
|
||||
// Dropping strategy : Keep only the p largest elements per column, where p is the number of elements in the column of the original matrix. Other strategies will be added
|
||||
|
||||
|
||||
// Apply the fill-reducing permutation computed in analyzePattern()
|
||||
if (m_perm.rows() == mat.rows() ) // To detect the null permutation
|
||||
{
|
||||
@@ -206,8 +206,8 @@ void IncompleteCholesky<Scalar,_UpLo, OrderingType>::factorize(const _MatrixType
|
||||
{
|
||||
m_L.template selfadjointView<Lower>() = mat.template selfadjointView<_UpLo>();
|
||||
}
|
||||
|
||||
Index n = m_L.cols();
|
||||
|
||||
Index n = m_L.cols();
|
||||
Index nnz = m_L.nonZeros();
|
||||
Map<VectorSx> vals(m_L.valuePtr(), nnz); //values
|
||||
Map<VectorIx> rowIdx(m_L.innerIndexPtr(), nnz); //Row indices
|
||||
@@ -219,9 +219,9 @@ void IncompleteCholesky<Scalar,_UpLo, OrderingType>::factorize(const _MatrixType
|
||||
VectorIx col_pattern(n);
|
||||
col_pattern.fill(-1);
|
||||
StorageIndex col_nnz;
|
||||
|
||||
|
||||
// Computes the scaling factors
|
||||
|
||||
|
||||
// Computes the scaling factors
|
||||
m_scale.resize(n);
|
||||
m_scale.setZero();
|
||||
for (Index j = 0; j < n; j++)
|
||||
@@ -231,7 +231,7 @@ void IncompleteCholesky<Scalar,_UpLo, OrderingType>::factorize(const _MatrixType
|
||||
if(rowIdx[k]!=j)
|
||||
m_scale(rowIdx[k]) += numext::abs2(vals(k));
|
||||
}
|
||||
|
||||
|
||||
m_scale = m_scale.cwiseSqrt().cwiseSqrt();
|
||||
|
||||
for (Index j = 0; j < n; ++j)
|
||||
@@ -241,8 +241,8 @@ void IncompleteCholesky<Scalar,_UpLo, OrderingType>::factorize(const _MatrixType
|
||||
m_scale(j) = 1;
|
||||
|
||||
// TODO disable scaling if not needed, i.e., if it is roughly uniform? (this will make solve() faster)
|
||||
|
||||
// Scale and compute the shift for the matrix
|
||||
|
||||
// Scale and compute the shift for the matrix
|
||||
RealScalar mindiag = NumTraits<RealScalar>::highest();
|
||||
for (Index j = 0; j < n; j++)
|
||||
{
|
||||
@@ -253,7 +253,7 @@ void IncompleteCholesky<Scalar,_UpLo, OrderingType>::factorize(const _MatrixType
|
||||
}
|
||||
|
||||
FactorType L_save = m_L;
|
||||
|
||||
|
||||
RealScalar shift = 0;
|
||||
if(mindiag <= RealScalar(0.))
|
||||
shift = m_initialShift - mindiag;
|
||||
@@ -375,7 +375,7 @@ inline void IncompleteCholesky<Scalar,_UpLo, OrderingType>::updateList(Ref<const
|
||||
if (jk < colPtr(col+1) )
|
||||
{
|
||||
Index p = colPtr(col+1) - jk;
|
||||
Index minpos;
|
||||
Index minpos;
|
||||
rowIdx.segment(jk,p).minCoeff(&minpos);
|
||||
minpos += jk;
|
||||
if (rowIdx(minpos) != rowIdx(jk))
|
||||
@@ -389,6 +389,6 @@ inline void IncompleteCholesky<Scalar,_UpLo, OrderingType>::updateList(Ref<const
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif
|
||||
|
||||
@@ -12,19 +12,19 @@
|
||||
#define EIGEN_INCOMPLETE_LUT_H
|
||||
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
|
||||
/** \internal
|
||||
* Compute a quick-sort split of a vector
|
||||
* Compute a quick-sort split of a vector
|
||||
* On output, the vector row is permuted such that its elements satisfy
|
||||
* abs(row(i)) >= abs(row(ncut)) if i<ncut
|
||||
* abs(row(i)) <= abs(row(ncut)) if i>ncut
|
||||
* abs(row(i)) <= abs(row(ncut)) if i>ncut
|
||||
* \param row The vector of values
|
||||
* \param ind The array of index for the elements in @p row
|
||||
* \param ncut The number of largest elements to keep
|
||||
**/
|
||||
**/
|
||||
template <typename VectorV, typename VectorI>
|
||||
Index QuickSplit(VectorV &row, VectorI &ind, Index ncut)
|
||||
{
|
||||
@@ -34,15 +34,15 @@ Index QuickSplit(VectorV &row, VectorI &ind, Index ncut)
|
||||
Index mid;
|
||||
Index n = row.size(); /* length of the vector */
|
||||
Index first, last ;
|
||||
|
||||
|
||||
ncut--; /* to fit the zero-based indices */
|
||||
first = 0;
|
||||
last = n-1;
|
||||
first = 0;
|
||||
last = n-1;
|
||||
if (ncut < first || ncut > last ) return 0;
|
||||
|
||||
|
||||
do {
|
||||
mid = first;
|
||||
RealScalar abskey = abs(row(mid));
|
||||
mid = first;
|
||||
RealScalar abskey = abs(row(mid));
|
||||
for (Index j = first + 1; j <= last; j++) {
|
||||
if ( abs(row(j)) > abskey) {
|
||||
++mid;
|
||||
@@ -53,12 +53,12 @@ Index QuickSplit(VectorV &row, VectorI &ind, Index ncut)
|
||||
/* Interchange for the pivot element */
|
||||
swap(row(mid), row(first));
|
||||
swap(ind(mid), ind(first));
|
||||
|
||||
|
||||
if (mid > ncut) last = mid - 1;
|
||||
else if (mid < ncut ) first = mid + 1;
|
||||
else if (mid < ncut ) first = mid + 1;
|
||||
} while (mid != ncut );
|
||||
|
||||
return 0; /* mid is equal to ncut */
|
||||
|
||||
return 0; /* mid is equal to ncut */
|
||||
}
|
||||
|
||||
}// end namespace internal
|
||||
@@ -71,23 +71,23 @@ Index QuickSplit(VectorV &row, VectorI &ind, Index ncut)
|
||||
*
|
||||
* During the numerical factorization, two dropping rules are used :
|
||||
* 1) any element whose magnitude is less than some tolerance is dropped.
|
||||
* This tolerance is obtained by multiplying the input tolerance @p droptol
|
||||
* This tolerance is obtained by multiplying the input tolerance @p droptol
|
||||
* by the average magnitude of all the original elements in the current row.
|
||||
* 2) After the elimination of the row, only the @p fill largest elements in
|
||||
* the L part and the @p fill largest elements in the U part are kept
|
||||
* (in addition to the diagonal element ). Note that @p fill is computed from
|
||||
* the input parameter @p fillfactor which is used the ratio to control the fill_in
|
||||
* 2) After the elimination of the row, only the @p fill largest elements in
|
||||
* the L part and the @p fill largest elements in the U part are kept
|
||||
* (in addition to the diagonal element ). Note that @p fill is computed from
|
||||
* the input parameter @p fillfactor which is used the ratio to control the fill_in
|
||||
* relatively to the initial number of nonzero elements.
|
||||
*
|
||||
*
|
||||
* The two extreme cases are when @p droptol=0 (to keep all the @p fill*2 largest elements)
|
||||
* and when @p fill=n/2 with @p droptol being different to zero.
|
||||
*
|
||||
* References : Yousef Saad, ILUT: A dual threshold incomplete LU factorization,
|
||||
* and when @p fill=n/2 with @p droptol being different to zero.
|
||||
*
|
||||
* References : Yousef Saad, ILUT: A dual threshold incomplete LU factorization,
|
||||
* Numerical Linear Algebra with Applications, 1(4), pp 387-402, 1994.
|
||||
*
|
||||
*
|
||||
* NOTE : The following implementation is derived from the ILUT implementation
|
||||
* in the SPARSKIT package, Copyright (C) 2005, the Regents of the University of Minnesota
|
||||
* released under the terms of the GNU LGPL:
|
||||
* in the SPARSKIT package, Copyright (C) 2005, the Regents of the University of Minnesota
|
||||
* released under the terms of the GNU LGPL:
|
||||
* http://www-users.cs.umn.edu/~saad/software/SPARSKIT/README
|
||||
* However, Yousef Saad gave us permission to relicense his ILUT code to MPL2.
|
||||
* See the Eigen mailing list archive, thread: ILUT, date: July 8, 2012:
|
||||
@@ -115,24 +115,24 @@ class IncompleteLUT : public SparseSolverBase<IncompleteLUT<_Scalar, _StorageInd
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
|
||||
IncompleteLUT()
|
||||
: m_droptol(NumTraits<Scalar>::dummy_precision()), m_fillfactor(10),
|
||||
m_analysisIsOk(false), m_factorizationIsOk(false)
|
||||
{}
|
||||
|
||||
|
||||
template<typename MatrixType>
|
||||
explicit IncompleteLUT(const MatrixType& mat, const RealScalar& droptol=NumTraits<Scalar>::dummy_precision(), int fillfactor = 10)
|
||||
: m_droptol(droptol),m_fillfactor(fillfactor),
|
||||
m_analysisIsOk(false),m_factorizationIsOk(false)
|
||||
{
|
||||
eigen_assert(fillfactor != 0);
|
||||
compute(mat);
|
||||
compute(mat);
|
||||
}
|
||||
|
||||
Index rows() const { return m_lu.rows(); }
|
||||
|
||||
Index cols() const { return m_lu.cols(); }
|
||||
|
||||
EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_lu.rows(); }
|
||||
|
||||
EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_lu.cols(); }
|
||||
|
||||
/** \brief Reports whether previous computation was successful.
|
||||
*
|
||||
@@ -144,36 +144,36 @@ class IncompleteLUT : public SparseSolverBase<IncompleteLUT<_Scalar, _StorageInd
|
||||
eigen_assert(m_isInitialized && "IncompleteLUT is not initialized.");
|
||||
return m_info;
|
||||
}
|
||||
|
||||
|
||||
template<typename MatrixType>
|
||||
void analyzePattern(const MatrixType& amat);
|
||||
|
||||
|
||||
template<typename MatrixType>
|
||||
void factorize(const MatrixType& amat);
|
||||
|
||||
|
||||
/**
|
||||
* Compute an incomplete LU factorization with dual threshold on the matrix mat
|
||||
* No pivoting is done in this version
|
||||
*
|
||||
*
|
||||
**/
|
||||
template<typename MatrixType>
|
||||
IncompleteLUT& compute(const MatrixType& amat)
|
||||
{
|
||||
analyzePattern(amat);
|
||||
analyzePattern(amat);
|
||||
factorize(amat);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void setDroptol(const RealScalar& droptol);
|
||||
void setFillfactor(int fillfactor);
|
||||
|
||||
void setDroptol(const RealScalar& droptol);
|
||||
void setFillfactor(int fillfactor);
|
||||
|
||||
template<typename Rhs, typename Dest>
|
||||
void _solve_impl(const Rhs& b, Dest& x) const
|
||||
{
|
||||
x = m_Pinv * b;
|
||||
x = m_lu.template triangularView<UnitLower>().solve(x);
|
||||
x = m_lu.template triangularView<Upper>().solve(x);
|
||||
x = m_P * x;
|
||||
x = m_P * x;
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -200,22 +200,22 @@ protected:
|
||||
|
||||
/**
|
||||
* Set control parameter droptol
|
||||
* \param droptol Drop any element whose magnitude is less than this tolerance
|
||||
**/
|
||||
* \param droptol Drop any element whose magnitude is less than this tolerance
|
||||
**/
|
||||
template<typename Scalar, typename StorageIndex>
|
||||
void IncompleteLUT<Scalar,StorageIndex>::setDroptol(const RealScalar& droptol)
|
||||
{
|
||||
this->m_droptol = droptol;
|
||||
this->m_droptol = droptol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set control parameter fillfactor
|
||||
* \param fillfactor This is used to compute the number @p fill_in of largest elements to keep on each row.
|
||||
**/
|
||||
* \param fillfactor This is used to compute the number @p fill_in of largest elements to keep on each row.
|
||||
**/
|
||||
template<typename Scalar, typename StorageIndex>
|
||||
void IncompleteLUT<Scalar,StorageIndex>::setFillfactor(int fillfactor)
|
||||
{
|
||||
this->m_fillfactor = fillfactor;
|
||||
this->m_fillfactor = fillfactor;
|
||||
}
|
||||
|
||||
template <typename Scalar, typename StorageIndex>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#ifndef EIGEN_ITERATIVE_SOLVER_BASE_H
|
||||
#define EIGEN_ITERATIVE_SOLVER_BASE_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
@@ -145,7 +145,7 @@ class IterativeSolverBase : public SparseSolverBase<Derived>
|
||||
protected:
|
||||
typedef SparseSolverBase<Derived> Base;
|
||||
using Base::m_isInitialized;
|
||||
|
||||
|
||||
public:
|
||||
typedef typename internal::traits<Derived>::MatrixType MatrixType;
|
||||
typedef typename internal::traits<Derived>::Preconditioner Preconditioner;
|
||||
@@ -169,10 +169,10 @@ public:
|
||||
}
|
||||
|
||||
/** Initialize the solver with matrix \a A for further \c Ax=b solving.
|
||||
*
|
||||
*
|
||||
* This constructor is a shortcut for the default constructor followed
|
||||
* by a call to compute().
|
||||
*
|
||||
*
|
||||
* \warning this class stores a reference to the matrix A as well as some
|
||||
* precomputed values that depend on it. Therefore, if \a A is changed
|
||||
* this class becomes invalid. Call compute() to update it with the new
|
||||
@@ -187,7 +187,7 @@ public:
|
||||
}
|
||||
|
||||
~IterativeSolverBase() {}
|
||||
|
||||
|
||||
/** Initializes the iterative solver for the sparsity pattern of the matrix \a A for further solving \c Ax=b problems.
|
||||
*
|
||||
* Currently, this function mostly calls analyzePattern on the preconditioner. In the future
|
||||
@@ -203,7 +203,7 @@ public:
|
||||
m_info = m_preconditioner.info();
|
||||
return derived();
|
||||
}
|
||||
|
||||
|
||||
/** Initializes the iterative solver with the numerical values of the matrix \a A for further solving \c Ax=b problems.
|
||||
*
|
||||
* Currently, this function mostly calls factorize on the preconditioner.
|
||||
@@ -216,7 +216,7 @@ public:
|
||||
template<typename MatrixDerived>
|
||||
Derived& factorize(const EigenBase<MatrixDerived>& A)
|
||||
{
|
||||
eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
|
||||
eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
|
||||
grab(A.derived());
|
||||
m_preconditioner.factorize(matrix());
|
||||
m_factorizationIsOk = true;
|
||||
@@ -247,16 +247,16 @@ public:
|
||||
}
|
||||
|
||||
/** \internal */
|
||||
Index rows() const { return matrix().rows(); }
|
||||
EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return matrix().rows(); }
|
||||
|
||||
/** \internal */
|
||||
Index cols() const { return matrix().cols(); }
|
||||
EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return matrix().cols(); }
|
||||
|
||||
/** \returns the tolerance threshold used by the stopping criteria.
|
||||
* \sa setTolerance()
|
||||
*/
|
||||
RealScalar tolerance() const { return m_tolerance; }
|
||||
|
||||
|
||||
/** Sets the tolerance threshold used by the stopping criteria.
|
||||
*
|
||||
* This value is used as an upper bound to the relative residual error: |Ax-b|/|b|.
|
||||
@@ -270,7 +270,7 @@ public:
|
||||
|
||||
/** \returns a read-write reference to the preconditioner for custom configuration. */
|
||||
Preconditioner& preconditioner() { return m_preconditioner; }
|
||||
|
||||
|
||||
/** \returns a read-only reference to the preconditioner. */
|
||||
const Preconditioner& preconditioner() const { return m_preconditioner; }
|
||||
|
||||
@@ -282,7 +282,7 @@ public:
|
||||
{
|
||||
return (m_maxIterations<0) ? 2*matrix().cols() : m_maxIterations;
|
||||
}
|
||||
|
||||
|
||||
/** Sets the max number of iterations.
|
||||
* Default is twice the number of columns of the matrix.
|
||||
*/
|
||||
@@ -328,13 +328,13 @@ public:
|
||||
eigen_assert(m_isInitialized && "IterativeSolverBase is not initialized.");
|
||||
return m_info;
|
||||
}
|
||||
|
||||
|
||||
/** \internal */
|
||||
template<typename Rhs, typename DestDerived>
|
||||
void _solve_with_guess_impl(const Rhs& b, SparseMatrixBase<DestDerived> &aDest) const
|
||||
{
|
||||
eigen_assert(rows()==b.rows());
|
||||
|
||||
|
||||
Index rhsCols = b.cols();
|
||||
Index size = b.rows();
|
||||
DestDerived& dest(aDest.derived());
|
||||
@@ -368,7 +368,7 @@ public:
|
||||
_solve_with_guess_impl(const Rhs& b, MatrixBase<DestDerived> &aDest) const
|
||||
{
|
||||
eigen_assert(rows()==b.rows());
|
||||
|
||||
|
||||
Index rhsCols = b.cols();
|
||||
DestDerived& dest(aDest.derived());
|
||||
ComputationInfo global_info = Success;
|
||||
@@ -420,19 +420,19 @@ protected:
|
||||
{
|
||||
return m_matrixWrapper.matrix();
|
||||
}
|
||||
|
||||
|
||||
template<typename InputType>
|
||||
void grab(const InputType &A)
|
||||
{
|
||||
m_matrixWrapper.grab(A);
|
||||
}
|
||||
|
||||
|
||||
MatrixWrapper m_matrixWrapper;
|
||||
Preconditioner m_preconditioner;
|
||||
|
||||
Index m_maxIterations;
|
||||
RealScalar m_tolerance;
|
||||
|
||||
|
||||
mutable RealScalar m_error;
|
||||
mutable Index m_iterations;
|
||||
mutable ComputationInfo m_info;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
namespace Eigen {
|
||||
|
||||
template<typename Decomposition, typename RhsType, typename GuessType> class SolveWithGuess;
|
||||
|
||||
|
||||
/** \class SolveWithGuess
|
||||
* \ingroup IterativeLinearSolvers_Module
|
||||
*
|
||||
@@ -45,13 +45,15 @@ public:
|
||||
typedef typename internal::traits<SolveWithGuess>::PlainObject PlainObject;
|
||||
typedef typename internal::generic_xpr_base<SolveWithGuess<Decomposition,RhsType,GuessType>, MatrixXpr, typename internal::traits<RhsType>::StorageKind>::type Base;
|
||||
typedef typename internal::ref_selector<SolveWithGuess>::type Nested;
|
||||
|
||||
|
||||
SolveWithGuess(const Decomposition &dec, const RhsType &rhs, const GuessType &guess)
|
||||
: m_dec(dec), m_rhs(rhs), m_guess(guess)
|
||||
{}
|
||||
|
||||
EIGEN_DEVICE_FUNC Index rows() const { return m_dec.cols(); }
|
||||
EIGEN_DEVICE_FUNC Index cols() const { return m_rhs.cols(); }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
Index rows() const EIGEN_NOEXCEPT { return m_dec.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 RhsType& rhs() const { return m_rhs; }
|
||||
@@ -61,7 +63,7 @@ protected:
|
||||
const Decomposition &m_dec;
|
||||
const RhsType &m_rhs;
|
||||
const GuessType &m_guess;
|
||||
|
||||
|
||||
private:
|
||||
Scalar coeff(Index row, Index col) const;
|
||||
Scalar coeff(Index i) const;
|
||||
@@ -85,8 +87,8 @@ struct evaluator<SolveWithGuess<Decomposition,RhsType, GuessType> >
|
||||
m_result = solve.guess();
|
||||
solve.dec()._solve_with_guess_impl(solve.rhs(), m_result);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
protected:
|
||||
PlainObject m_result;
|
||||
};
|
||||
|
||||
|
||||
@@ -453,7 +453,7 @@ EIGEN_DEVICE_FUNC
|
||||
void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(DenseBase<VectorX>& xpr_x, DenseBase<VectorY>& xpr_y, const JacobiRotation<OtherScalar>& j)
|
||||
{
|
||||
typedef typename VectorX::Scalar Scalar;
|
||||
const bool Vectorizable = (VectorX::Flags & VectorY::Flags & PacketAccessBit)
|
||||
const bool Vectorizable = (int(VectorX::Flags) & int(VectorY::Flags) & PacketAccessBit)
|
||||
&& (int(packet_traits<Scalar>::size) == int(packet_traits<OtherScalar>::size));
|
||||
|
||||
eigen_assert(xpr_x.size() == xpr_y.size());
|
||||
|
||||
@@ -101,8 +101,8 @@ class KLU : public SparseSolverBase<KLU<_MatrixType> >
|
||||
if(m_numeric) klu_free_numeric(&m_numeric,&m_common);
|
||||
}
|
||||
|
||||
inline Index rows() const { return mp_matrix.rows(); }
|
||||
inline Index cols() const { return mp_matrix.cols(); }
|
||||
EIGEN_CONSTEXPR inline Index rows() const EIGEN_NOEXCEPT { return mp_matrix.rows(); }
|
||||
EIGEN_CONSTEXPR inline Index cols() const EIGEN_NOEXCEPT { return mp_matrix.cols(); }
|
||||
|
||||
/** \brief Reports whether previous computation was successful.
|
||||
*
|
||||
@@ -253,7 +253,7 @@ class KLU : public SparseSolverBase<KLU<_MatrixType> >
|
||||
|
||||
m_numeric = klu_factor(const_cast<StorageIndex*>(mp_matrix.outerIndexPtr()), const_cast<StorageIndex*>(mp_matrix.innerIndexPtr()), const_cast<Scalar*>(mp_matrix.valuePtr()),
|
||||
m_symbolic, &m_common, Scalar());
|
||||
|
||||
|
||||
|
||||
m_info = m_numeric ? Success : NumericalIssue;
|
||||
m_factorizationIsOk = m_numeric ? 1 : 0;
|
||||
|
||||
@@ -404,8 +404,10 @@ template<typename _MatrixType> class FullPivLU
|
||||
|
||||
MatrixType reconstructedMatrix() const;
|
||||
|
||||
EIGEN_DEVICE_FUNC inline Index rows() const { return m_lu.rows(); }
|
||||
EIGEN_DEVICE_FUNC inline Index cols() const { return m_lu.cols(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index rows() const EIGEN_NOEXCEPT { return m_lu.rows(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
inline Index cols() const EIGEN_NOEXCEPT { return m_lu.cols(); }
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
template<typename RhsType, typename DstType>
|
||||
|
||||
@@ -70,7 +70,7 @@ struct enable_if_ref<Ref<T>,Derived> {
|
||||
* The data of the LU decomposition can be directly accessed through the methods matrixLU(), permutationP().
|
||||
*
|
||||
* This class supports the \link InplaceDecomposition inplace decomposition \endlink mechanism.
|
||||
*
|
||||
*
|
||||
* \sa MatrixBase::partialPivLu(), MatrixBase::determinant(), MatrixBase::inverse(), MatrixBase::computeInverse(), class FullPivLU
|
||||
*/
|
||||
template<typename _MatrixType> class PartialPivLU
|
||||
@@ -216,8 +216,8 @@ template<typename _MatrixType> class PartialPivLU
|
||||
|
||||
MatrixType reconstructedMatrix() const;
|
||||
|
||||
inline Index rows() const { return m_lu.rows(); }
|
||||
inline Index cols() const { return m_lu.cols(); }
|
||||
EIGEN_CONSTEXPR inline Index rows() const EIGEN_NOEXCEPT { return m_lu.rows(); }
|
||||
EIGEN_CONSTEXPR inline Index cols() const EIGEN_NOEXCEPT { return m_lu.cols(); }
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
template<typename RhsType, typename DstType>
|
||||
|
||||
@@ -287,8 +287,8 @@ template<typename _MatrixType, int _UpLo, typename _Ordering> struct traits<Simp
|
||||
typedef SparseMatrix<Scalar, ColMajor, StorageIndex> CholMatrixType;
|
||||
typedef TriangularView<const CholMatrixType, Eigen::Lower> MatrixL;
|
||||
typedef TriangularView<const typename CholMatrixType::AdjointReturnType, Eigen::Upper> MatrixU;
|
||||
static inline MatrixL getL(const MatrixType& m) { return MatrixL(m); }
|
||||
static inline MatrixU getU(const MatrixType& m) { return MatrixU(m.adjoint()); }
|
||||
static inline MatrixL getL(const CholMatrixType& m) { return MatrixL(m); }
|
||||
static inline MatrixU getU(const CholMatrixType& m) { return MatrixU(m.adjoint()); }
|
||||
};
|
||||
|
||||
template<typename _MatrixType,int _UpLo, typename _Ordering> struct traits<SimplicialLDLT<_MatrixType,_UpLo,_Ordering> >
|
||||
@@ -301,8 +301,8 @@ template<typename _MatrixType,int _UpLo, typename _Ordering> struct traits<Simpl
|
||||
typedef SparseMatrix<Scalar, ColMajor, StorageIndex> CholMatrixType;
|
||||
typedef TriangularView<const CholMatrixType, Eigen::UnitLower> MatrixL;
|
||||
typedef TriangularView<const typename CholMatrixType::AdjointReturnType, Eigen::UnitUpper> MatrixU;
|
||||
static inline MatrixL getL(const MatrixType& m) { return MatrixL(m); }
|
||||
static inline MatrixU getU(const MatrixType& m) { return MatrixU(m.adjoint()); }
|
||||
static inline MatrixL getL(const CholMatrixType& m) { return MatrixL(m); }
|
||||
static inline MatrixU getU(const CholMatrixType& m) { return MatrixU(m.adjoint()); }
|
||||
};
|
||||
|
||||
template<typename _MatrixType, int _UpLo, typename _Ordering> struct traits<SimplicialCholesky<_MatrixType,_UpLo,_Ordering> >
|
||||
|
||||
@@ -579,10 +579,12 @@ class SparseMatrix
|
||||
else if (innerChange < 0)
|
||||
{
|
||||
// Inner size decreased: allocate a new m_innerNonZeros
|
||||
m_innerNonZeros = static_cast<StorageIndex*>(std::malloc((m_outerSize+outerChange+1) * sizeof(StorageIndex)));
|
||||
m_innerNonZeros = static_cast<StorageIndex*>(std::malloc((m_outerSize + outerChange) * sizeof(StorageIndex)));
|
||||
if (!m_innerNonZeros) internal::throw_std_bad_alloc();
|
||||
for(Index i = 0; i < m_outerSize; i++)
|
||||
for(Index i = 0; i < m_outerSize + (std::min)(outerChange, Index(0)); i++)
|
||||
m_innerNonZeros[i] = m_outerIndex[i+1] - m_outerIndex[i];
|
||||
for(Index i = m_outerSize; i < m_outerSize + outerChange; i++)
|
||||
m_innerNonZeros[i] = 0;
|
||||
}
|
||||
|
||||
// Change the m_innerNonZeros in case of a decrease of inner size
|
||||
|
||||
@@ -142,6 +142,9 @@ template<typename MatrixType, unsigned int _Mode> class SparseSelfAdjointView
|
||||
return *this = src.twistedBy(pnull);
|
||||
}
|
||||
|
||||
// Since we override the copy-assignment operator, we need to explicitly re-declare the copy-constructor
|
||||
EIGEN_DEFAULT_COPY_CONSTRUCTOR(SparseSelfAdjointView)
|
||||
|
||||
template<typename SrcMatrixType,unsigned int SrcMode>
|
||||
SparseSelfAdjointView& operator=(const SparseSelfAdjointView<SrcMatrixType,SrcMode>& src)
|
||||
{
|
||||
|
||||
@@ -217,12 +217,12 @@ struct SluMatrix : SuperMatrix
|
||||
res.setScalarType<typename MatrixType::Scalar>();
|
||||
|
||||
// FIXME the following is not very accurate
|
||||
if (MatrixType::Flags & Upper)
|
||||
if (int(MatrixType::Flags) & int(Upper))
|
||||
res.Mtype = SLU_TRU;
|
||||
if (MatrixType::Flags & Lower)
|
||||
if (int(MatrixType::Flags) & int(Lower))
|
||||
res.Mtype = SLU_TRL;
|
||||
|
||||
eigen_assert(((MatrixType::Flags & SelfAdjoint)==0) && "SelfAdjoint matrix shape not supported by SuperLU");
|
||||
eigen_assert(((int(MatrixType::Flags) & int(SelfAdjoint))==0) && "SelfAdjoint matrix shape not supported by SuperLU");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -1437,7 +1437,6 @@ subVector(Index i) const
|
||||
* \sa subVector(Index)
|
||||
*/
|
||||
template<DirectionType Direction>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
|
||||
Index subVectors() const
|
||||
{ return (Direction==Vertical)?cols():rows(); }
|
||||
|
||||
|
||||
@@ -111,12 +111,12 @@ EIGEN_DONT_INLINE typename T::Scalar pblueNorm(const T& v)
|
||||
int nbig, ibeta, it, iemin, iemax, iexp;
|
||||
Scalar abig, eps;
|
||||
|
||||
nbig = std::numeric_limits<int>::max(); // largest integer
|
||||
ibeta = std::numeric_limits<Scalar>::radix; //NumTraits<Scalar>::Base; // base for floating-point numbers
|
||||
it = std::numeric_limits<Scalar>::digits; //NumTraits<Scalar>::Mantissa; // number of base-beta digits in mantissa
|
||||
iemin = std::numeric_limits<Scalar>::min_exponent; // minimum exponent
|
||||
iemax = std::numeric_limits<Scalar>::max_exponent; // maximum exponent
|
||||
rbig = std::numeric_limits<Scalar>::max(); // largest floating-point number
|
||||
nbig = NumTraits<int>::highest(); // largest integer
|
||||
ibeta = std::numeric_limits<Scalar>::radix; // NumTraits<Scalar>::Base; // base for floating-point numbers
|
||||
it = NumTraits<Scalar>::digits(); // NumTraits<Scalar>::Mantissa; // number of base-beta digits in mantissa
|
||||
iemin = NumTraits<Scalar>::min_exponent(); // minimum exponent
|
||||
iemax = NumTraits<Scalar>::max_exponent(); // maximum exponent
|
||||
rbig = NumTraits<Scalar>::highest(); // largest floating-point number
|
||||
|
||||
// Check the basic machine-dependent constants.
|
||||
if(iemin > 1 - 2*it || 1+it>iemax || (it==2 && ibeta<5)
|
||||
|
||||
@@ -13,7 +13,7 @@ set(SPARSE_LIBS "")
|
||||
# set(SPARSE_LIBS ${SPARSE_LIBS} ${PARDISO_LIBRARIES})
|
||||
# endif()
|
||||
|
||||
find_package(Cholmod)
|
||||
find_package(CHOLMOD)
|
||||
if(CHOLMOD_FOUND AND BLAS_FOUND AND LAPACK_FOUND)
|
||||
add_definitions("-DEIGEN_CHOLMOD_SUPPORT")
|
||||
include_directories(${CHOLMOD_INCLUDES})
|
||||
@@ -21,7 +21,7 @@ if(CHOLMOD_FOUND AND BLAS_FOUND AND LAPACK_FOUND)
|
||||
set(CHOLMOD_ALL_LIBS ${CHOLMOD_LIBRARIES} ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES})
|
||||
endif()
|
||||
|
||||
find_package(Umfpack)
|
||||
find_package(UMFPACK)
|
||||
if(UMFPACK_FOUND AND BLAS_FOUND)
|
||||
add_definitions("-DEIGEN_UMFPACK_SUPPORT")
|
||||
include_directories(${UMFPACK_INCLUDES})
|
||||
@@ -37,7 +37,7 @@ if(KLU_FOUND)
|
||||
endif()
|
||||
|
||||
find_package(SuperLU 4.0)
|
||||
if(SUPERLU_FOUND AND BLAS_FOUND)
|
||||
if(SuperLU_FOUND AND BLAS_FOUND)
|
||||
add_definitions("-DEIGEN_SUPERLU_SUPPORT")
|
||||
include_directories(${SUPERLU_INCLUDES})
|
||||
set(SPARSE_LIBS ${SPARSE_LIBS} ${SUPERLU_LIBRARIES} ${BLAS_LIBRARIES})
|
||||
|
||||
@@ -190,7 +190,7 @@ build:ppc64le:linux:gcc-10:cxx11-on:
|
||||
- linux
|
||||
- ppc64le
|
||||
|
||||
# Clang-10
|
||||
# # Clang-10
|
||||
build:ppc64le:linux:clang-10:cxx11-off:
|
||||
allow_failure: true
|
||||
extends: .build:linux:base
|
||||
|
||||
@@ -342,7 +342,7 @@ test:ppc64le:linux:gcc-10:cxx11-on:unsupported:
|
||||
variables:
|
||||
EIGEN_CI_TEST_LABEL: "Unsupported"
|
||||
|
||||
# Clang 10
|
||||
# # Clang 10
|
||||
.test:ppc64le:linux:clang-10:cxx11-off:
|
||||
extends: .test:linux:base
|
||||
variables:
|
||||
|
||||
@@ -4,17 +4,17 @@ if (ADOLC_INCLUDES AND ADOLC_LIBRARIES)
|
||||
endif ()
|
||||
|
||||
find_path(ADOLC_INCLUDES
|
||||
NAMES
|
||||
adolc/adtl.h
|
||||
PATHS
|
||||
$ENV{ADOLCDIR}
|
||||
${INCLUDE_INSTALL_DIR}
|
||||
NAMES adolc/adtl.h
|
||||
PATHS $ENV{ADOLCDIR} $ENV{ADOLCDIR}/include ${INCLUDE_INSTALL_DIR}
|
||||
)
|
||||
|
||||
find_library(ADOLC_LIBRARIES adolc PATHS $ENV{ADOLCDIR} ${LIB_INSTALL_DIR})
|
||||
find_library(ADOLC_LIBRARIES
|
||||
adolc
|
||||
PATHS $ENV{ADOLCDIR} ${LIB_INSTALL_DIR}
|
||||
PATH_SUFFIXES lib lib64)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(ADOLC DEFAULT_MSG
|
||||
find_package_handle_standard_args(Adolc DEFAULT_MSG
|
||||
ADOLC_INCLUDES ADOLC_LIBRARIES)
|
||||
|
||||
mark_as_advanced(ADOLC_INCLUDES ADOLC_LIBRARIES)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user