mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-14 20:56:00 +08:00
add RealView api
This commit is contained in:
parent
954e21152e
commit
43a65a9cbd
@ -319,6 +319,7 @@ using std::ptrdiff_t;
|
||||
#include "src/Core/Product.h"
|
||||
#include "src/Core/CoreEvaluators.h"
|
||||
#include "src/Core/AssignEvaluator.h"
|
||||
#include "src/Core/RealView.h"
|
||||
#include "src/Core/Assign.h"
|
||||
|
||||
#include "src/Core/ArrayBase.h"
|
||||
|
@ -367,7 +367,12 @@ class DenseBase
|
||||
EIGEN_DEVICE_FUNC inline bool allFinite() const;
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator*=(const Scalar& other);
|
||||
template <bool Enable = !internal::is_same<Scalar, RealScalar>::value, typename = std::enable_if_t<Enable>>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator*=(const RealScalar& other);
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator/=(const Scalar& other);
|
||||
template <bool Enable = !internal::is_same<Scalar, RealScalar>::value, typename = std::enable_if_t<Enable>>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator/=(const RealScalar& other);
|
||||
|
||||
typedef internal::add_const_on_value_type_t<typename internal::eval<Derived>::type> EvalReturnType;
|
||||
/** \returns the matrix or vector obtained by evaluating this expression.
|
||||
@ -597,6 +602,13 @@ class DenseBase
|
||||
inline const_iterator end() const;
|
||||
inline const_iterator cend() const;
|
||||
|
||||
using RealViewReturnType = std::conditional_t<NumTraits<Scalar>::IsComplex, RealView<Derived>, Derived&>;
|
||||
using ConstRealViewReturnType =
|
||||
std::conditional_t<NumTraits<Scalar>::IsComplex, RealView<const Derived>, const Derived&>;
|
||||
|
||||
EIGEN_DEVICE_FUNC RealViewReturnType realView();
|
||||
EIGEN_DEVICE_FUNC ConstRealViewReturnType realView() const;
|
||||
|
||||
#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::DenseBase
|
||||
#define EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
|
||||
#define EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(COND)
|
||||
|
@ -253,6 +253,12 @@ struct preinterpret_generic<Packet, Packet, true> {
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run(const Packet& a) { return a; }
|
||||
};
|
||||
|
||||
template <typename ComplexPacket>
|
||||
struct preinterpret_generic<typename unpacket_traits<ComplexPacket>::as_real, ComplexPacket, false> {
|
||||
using RealPacket = typename unpacket_traits<ComplexPacket>::as_real;
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE RealPacket run(const ComplexPacket& a) { return a.v; }
|
||||
};
|
||||
|
||||
/** \internal \returns reinterpret_cast<Target>(a) */
|
||||
template <typename Target, typename Packet>
|
||||
EIGEN_DEVICE_FUNC inline Target preinterpret(const Packet& a) {
|
||||
|
250
Eigen/src/Core/RealView.h
Normal file
250
Eigen/src/Core/RealView.h
Normal file
@ -0,0 +1,250 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2025 Charlie Schlosser <cs.schlosser@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef EIGEN_REALVIEW_H
|
||||
#define EIGEN_REALVIEW_H
|
||||
|
||||
// IWYU pragma: private
|
||||
#include "./InternalHeaderCheck.h"
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Vectorized assignment to RealView requires array-oriented access to the real and imaginary components.
|
||||
// From https://en.cppreference.com/w/cpp/numeric/complex.html:
|
||||
// For any pointer to an element of an array of std::complex<T> named p and any valid array index i,
|
||||
// reinterpret_cast<T*>(p)[2 * i] is the real part of the complex number p[i], and
|
||||
// reinterpret_cast<T*>(p)[2 * i + 1] is the imaginary part of the complex number p[i].
|
||||
|
||||
template <typename ComplexScalar>
|
||||
struct complex_array_access : std::false_type {};
|
||||
template <>
|
||||
struct complex_array_access<std::complex<float>> : std::true_type {};
|
||||
template <>
|
||||
struct complex_array_access<std::complex<double>> : std::true_type {};
|
||||
template <>
|
||||
struct complex_array_access<std::complex<long double>> : std::true_type {};
|
||||
|
||||
template <typename Xpr>
|
||||
struct traits<RealView<Xpr>> : public traits<Xpr> {
|
||||
template <typename T>
|
||||
static constexpr int double_size(T size, bool times_two) {
|
||||
int size_as_int = int(size);
|
||||
if (size_as_int == Dynamic) return Dynamic;
|
||||
return times_two ? (2 * size_as_int) : size_as_int;
|
||||
}
|
||||
using Base = traits<Xpr>;
|
||||
using ComplexScalar = typename Base::Scalar;
|
||||
using Scalar = typename NumTraits<ComplexScalar>::Real;
|
||||
static constexpr int ActualDirectAccessBit = complex_array_access<ComplexScalar>::value ? DirectAccessBit : 0;
|
||||
static constexpr int ActualPacketAccessBit = packet_traits<Scalar>::Vectorizable ? PacketAccessBit : 0;
|
||||
static constexpr int FlagMask =
|
||||
ActualDirectAccessBit | ActualPacketAccessBit | HereditaryBits | LinearAccessBit | LvalueBit;
|
||||
static constexpr int BaseFlags = int(evaluator<Xpr>::Flags) | int(Base::Flags);
|
||||
static constexpr int Flags = BaseFlags & FlagMask;
|
||||
static constexpr bool IsRowMajor = Flags & RowMajorBit;
|
||||
static constexpr int RowsAtCompileTime = double_size(Base::RowsAtCompileTime, !IsRowMajor);
|
||||
static constexpr int ColsAtCompileTime = double_size(Base::ColsAtCompileTime, IsRowMajor);
|
||||
static constexpr int SizeAtCompileTime = size_at_compile_time(RowsAtCompileTime, ColsAtCompileTime);
|
||||
static constexpr int MaxRowsAtCompileTime = double_size(Base::MaxRowsAtCompileTime, !IsRowMajor);
|
||||
static constexpr int MaxColsAtCompileTime = double_size(Base::MaxColsAtCompileTime, IsRowMajor);
|
||||
static constexpr int MaxSizeAtCompileTime = size_at_compile_time(MaxRowsAtCompileTime, MaxColsAtCompileTime);
|
||||
static constexpr int OuterStrideAtCompileTime = double_size(outer_stride_at_compile_time<Xpr>::ret, true);
|
||||
static constexpr int InnerStrideAtCompileTime = inner_stride_at_compile_time<Xpr>::ret;
|
||||
};
|
||||
|
||||
template <typename Xpr>
|
||||
struct evaluator<RealView<Xpr>> : private evaluator<Xpr> {
|
||||
using BaseEvaluator = evaluator<Xpr>;
|
||||
using XprType = RealView<Xpr>;
|
||||
using ExpressionTraits = traits<XprType>;
|
||||
using ComplexScalar = typename ExpressionTraits::ComplexScalar;
|
||||
using ComplexCoeffReturnType = typename BaseEvaluator::CoeffReturnType;
|
||||
using Scalar = typename ExpressionTraits::Scalar;
|
||||
|
||||
static constexpr bool IsRowMajor = ExpressionTraits::IsRowMajor;
|
||||
static constexpr int Flags = ExpressionTraits::Flags;
|
||||
static constexpr int CoeffReadCost = BaseEvaluator::CoeffReadCost;
|
||||
static constexpr int Alignment = BaseEvaluator::Alignment;
|
||||
|
||||
EIGEN_DEVICE_FUNC explicit evaluator(XprType realView) : BaseEvaluator(realView.m_xpr) {}
|
||||
|
||||
template <bool Enable = std::is_reference<ComplexCoeffReturnType>::value, typename = std::enable_if_t<!Enable>>
|
||||
constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar coeff(Index row, Index col) const {
|
||||
ComplexCoeffReturnType cscalar = BaseEvaluator::coeff(IsRowMajor ? row : row / 2, IsRowMajor ? col / 2 : col);
|
||||
Index p = (IsRowMajor ? col : row) & 1;
|
||||
return p ? numext::real(cscalar) : numext::imag(cscalar);
|
||||
}
|
||||
|
||||
template <bool Enable = std::is_reference<ComplexCoeffReturnType>::value, typename = std::enable_if_t<Enable>>
|
||||
constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& coeff(Index row, Index col) const {
|
||||
ComplexCoeffReturnType cscalar = BaseEvaluator::coeff(IsRowMajor ? row : row / 2, IsRowMajor ? col / 2 : col);
|
||||
Index p = (IsRowMajor ? col : row) & 1;
|
||||
return reinterpret_cast<const Scalar(&)[2]>(cscalar)[p];
|
||||
}
|
||||
|
||||
constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col) {
|
||||
ComplexScalar& cscalar = BaseEvaluator::coeffRef(IsRowMajor ? row : row / 2, IsRowMajor ? col / 2 : col);
|
||||
Index p = (IsRowMajor ? col : row) & 1;
|
||||
return reinterpret_cast<Scalar(&)[2]>(cscalar)[p];
|
||||
}
|
||||
|
||||
template <bool Enable = std::is_reference<ComplexCoeffReturnType>::value, typename = std::enable_if_t<!Enable>>
|
||||
constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar coeff(Index index) const {
|
||||
ComplexCoeffReturnType cscalar = BaseEvaluator::coeff(index / 2);
|
||||
Index p = index & 1;
|
||||
return p ? numext::real(cscalar) : numext::imag(cscalar);
|
||||
}
|
||||
|
||||
template <bool Enable = std::is_reference<ComplexCoeffReturnType>::value, typename = std::enable_if_t<Enable>>
|
||||
constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const {
|
||||
ComplexCoeffReturnType cscalar = BaseEvaluator::coeff(index / 2);
|
||||
Index p = index & 1;
|
||||
return reinterpret_cast<const Scalar(&)[2]>(cscalar)[p];
|
||||
}
|
||||
|
||||
constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) {
|
||||
ComplexScalar& cscalar = BaseEvaluator::coeffRef(index / 2);
|
||||
Index p = index & 1;
|
||||
return reinterpret_cast<Scalar(&)[2]>(cscalar)[p];
|
||||
}
|
||||
|
||||
template <int LoadMode, typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index row, Index col) const {
|
||||
constexpr int RealPacketSize = unpacket_traits<PacketType>::size;
|
||||
using ComplexPacket = typename find_packet_by_size<ComplexScalar, RealPacketSize / 2>::type;
|
||||
EIGEN_STATIC_ASSERT((find_packet_by_size<ComplexScalar, RealPacketSize / 2>::value),
|
||||
MISSING COMPATIBLE COMPLEX PACKET TYPE)
|
||||
eigen_assert(((IsRowMajor ? col : row) % 2 == 0) && "the inner index must be even");
|
||||
|
||||
Index crow = IsRowMajor ? row : row / 2;
|
||||
Index ccol = IsRowMajor ? col / 2 : col;
|
||||
ComplexPacket cpacket = BaseEvaluator::template packet<LoadMode, ComplexPacket>(crow, ccol);
|
||||
return preinterpret<PacketType, ComplexPacket>(cpacket);
|
||||
}
|
||||
|
||||
template <int LoadMode, typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index index) const {
|
||||
constexpr int RealPacketSize = unpacket_traits<PacketType>::size;
|
||||
using ComplexPacket = typename find_packet_by_size<ComplexScalar, RealPacketSize / 2>::type;
|
||||
EIGEN_STATIC_ASSERT((find_packet_by_size<ComplexScalar, RealPacketSize / 2>::value),
|
||||
MISSING COMPATIBLE COMPLEX PACKET TYPE)
|
||||
eigen_assert((index % 2 == 0) && "the index must be even");
|
||||
|
||||
Index cindex = index / 2;
|
||||
ComplexPacket cpacket = BaseEvaluator::template packet<LoadMode, ComplexPacket>(cindex);
|
||||
return preinterpret<PacketType, ComplexPacket>(cpacket);
|
||||
}
|
||||
|
||||
template <int LoadMode, typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index row, Index col, Index begin, Index count) const {
|
||||
constexpr int RealPacketSize = unpacket_traits<PacketType>::size;
|
||||
using ComplexPacket = typename find_packet_by_size<ComplexScalar, RealPacketSize / 2>::type;
|
||||
EIGEN_STATIC_ASSERT((find_packet_by_size<ComplexScalar, RealPacketSize / 2>::value),
|
||||
MISSING COMPATIBLE COMPLEX PACKET TYPE)
|
||||
eigen_assert(((IsRowMajor ? col : row) % 2 == 0) && "the inner index must be even");
|
||||
eigen_assert((begin % 2 == 0) && (count % 2 == 0) && "begin and count must be even");
|
||||
|
||||
Index crow = IsRowMajor ? row : row / 2;
|
||||
Index ccol = IsRowMajor ? col / 2 : col;
|
||||
Index cbegin = begin / 2;
|
||||
Index ccount = count / 2;
|
||||
ComplexPacket cpacket = BaseEvaluator::template packetSegment<LoadMode, ComplexPacket>(crow, ccol, cbegin, ccount);
|
||||
return preinterpret<PacketType, ComplexPacket>(cpacket);
|
||||
}
|
||||
|
||||
template <int LoadMode, typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index index, Index begin, Index count) const {
|
||||
constexpr int RealPacketSize = unpacket_traits<PacketType>::size;
|
||||
using ComplexPacket = typename find_packet_by_size<ComplexScalar, RealPacketSize / 2>::type;
|
||||
EIGEN_STATIC_ASSERT((find_packet_by_size<ComplexScalar, RealPacketSize / 2>::value),
|
||||
MISSING COMPATIBLE COMPLEX PACKET TYPE)
|
||||
eigen_assert((index % 2 == 0) && "the index must be even");
|
||||
eigen_assert((begin % 2 == 0) && (count % 2 == 0) && "begin and count must be even");
|
||||
|
||||
Index cindex = index / 2;
|
||||
Index cbegin = begin / 2;
|
||||
Index ccount = count / 2;
|
||||
ComplexPacket cpacket = BaseEvaluator::template packetSegment<LoadMode, ComplexPacket>(cindex, cbegin, ccount);
|
||||
return preinterpret<PacketType, ComplexPacket>(cpacket);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename Xpr>
|
||||
class RealView : public internal::dense_xpr_base<RealView<Xpr>>::type {
|
||||
using ExpressionTraits = internal::traits<RealView>;
|
||||
EIGEN_STATIC_ASSERT(NumTraits<typename Xpr::Scalar>::IsComplex, SCALAR MUST BE COMPLEX)
|
||||
public:
|
||||
using Scalar = typename ExpressionTraits::Scalar;
|
||||
using Nested = RealView;
|
||||
|
||||
EIGEN_DEVICE_FUNC explicit RealView(Xpr& xpr) : m_xpr(xpr) {}
|
||||
EIGEN_DEVICE_FUNC constexpr Index rows() const noexcept { return Xpr::IsRowMajor ? m_xpr.rows() : 2 * m_xpr.rows(); }
|
||||
EIGEN_DEVICE_FUNC constexpr Index cols() const noexcept { return Xpr::IsRowMajor ? 2 * m_xpr.cols() : m_xpr.cols(); }
|
||||
EIGEN_DEVICE_FUNC constexpr Index size() const noexcept { return 2 * m_xpr.size(); }
|
||||
EIGEN_DEVICE_FUNC constexpr Index innerStride() const noexcept { return m_xpr.innerStride(); }
|
||||
EIGEN_DEVICE_FUNC constexpr Index outerStride() const noexcept { return 2 * m_xpr.outerStride(); }
|
||||
EIGEN_DEVICE_FUNC void resize(Index rows, Index cols) {
|
||||
m_xpr.resize(Xpr::IsRowMajor ? rows : rows / 2, Xpr::IsRowMajor ? cols / 2 : cols);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC void resize(Index size) { m_xpr.resize(size / 2); }
|
||||
EIGEN_DEVICE_FUNC Scalar* data() { return reinterpret_cast<Scalar*>(m_xpr.data()); }
|
||||
EIGEN_DEVICE_FUNC const Scalar* data() const { return reinterpret_cast<const Scalar*>(m_xpr.data()); }
|
||||
|
||||
EIGEN_DEVICE_FUNC RealView(const RealView&) = default;
|
||||
|
||||
EIGEN_DEVICE_FUNC RealView& operator=(const RealView& other);
|
||||
|
||||
template <typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC RealView& operator=(const RealView<OtherDerived>& other);
|
||||
|
||||
template <typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC RealView& operator=(const DenseBase<OtherDerived>& other);
|
||||
|
||||
protected:
|
||||
friend struct internal::evaluator<RealView<Xpr>>;
|
||||
Xpr& m_xpr;
|
||||
};
|
||||
|
||||
template <typename Xpr>
|
||||
EIGEN_DEVICE_FUNC RealView<Xpr>& RealView<Xpr>::operator=(const RealView& other) {
|
||||
internal::call_assignment(*this, other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Xpr>
|
||||
template <typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC RealView<Xpr>& RealView<Xpr>::operator=(const RealView<OtherDerived>& other) {
|
||||
internal::call_assignment(*this, other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Xpr>
|
||||
template <typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC RealView<Xpr>& RealView<Xpr>::operator=(const DenseBase<OtherDerived>& other) {
|
||||
internal::call_assignment(*this, other.derived());
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
EIGEN_DEVICE_FUNC typename DenseBase<Derived>::RealViewReturnType DenseBase<Derived>::realView() {
|
||||
return RealViewReturnType(derived());
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
EIGEN_DEVICE_FUNC typename DenseBase<Derived>::ConstRealViewReturnType DenseBase<Derived>::realView() const {
|
||||
return ConstRealViewReturnType(derived());
|
||||
}
|
||||
|
||||
} // namespace Eigen
|
||||
|
||||
#endif // EIGEN_REALVIEW_H
|
@ -15,19 +15,33 @@
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
// TODO generalize the scalar type of 'other'
|
||||
|
||||
template <typename Derived>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator*=(const Scalar& other) {
|
||||
internal::call_assignment(this->derived(), PlainObject::Constant(rows(), cols(), other),
|
||||
internal::mul_assign_op<Scalar, Scalar>());
|
||||
using ConstantExpr = typename internal::plain_constant_type<Derived, Scalar>::type;
|
||||
using Op = internal::mul_assign_op<Scalar>;
|
||||
internal::call_assignment(derived(), ConstantExpr(rows(), cols(), other), Op());
|
||||
return derived();
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
template <bool Enable, typename>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator*=(const RealScalar& other) {
|
||||
realView() *= other;
|
||||
return derived();
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator/=(const Scalar& other) {
|
||||
internal::call_assignment(this->derived(), PlainObject::Constant(rows(), cols(), other),
|
||||
internal::div_assign_op<Scalar, Scalar>());
|
||||
using ConstantExpr = typename internal::plain_constant_type<Derived, Scalar>::type;
|
||||
using Op = internal::div_assign_op<Scalar>;
|
||||
internal::call_assignment(derived(), ConstantExpr(rows(), cols(), other), Op());
|
||||
return derived();
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
template <bool Enable, typename>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator/=(const RealScalar& other) {
|
||||
realView() /= other;
|
||||
return derived();
|
||||
}
|
||||
|
||||
|
@ -171,6 +171,8 @@ template <typename MatrixType, unsigned int Mode>
|
||||
class TriangularView;
|
||||
template <typename MatrixType, unsigned int Mode>
|
||||
class SelfAdjointView;
|
||||
template <typename Derived>
|
||||
class RealView;
|
||||
template <typename MatrixType>
|
||||
class SparseView;
|
||||
template <typename ExpressionType>
|
||||
|
110
test/realview.cpp
Normal file
110
test/realview.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2025 The Eigen Authors
|
||||
//
|
||||
// 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/.
|
||||
|
||||
#include "main.h"
|
||||
|
||||
template <typename T>
|
||||
void test_realview(const T&) {
|
||||
using Scalar = typename T::Scalar;
|
||||
using RealScalar = typename NumTraits<Scalar>::Real;
|
||||
|
||||
constexpr Index minRows = T::RowsAtCompileTime == Dynamic ? 1 : T::RowsAtCompileTime;
|
||||
constexpr Index maxRows = T::MaxRowsAtCompileTime == Dynamic ? (EIGEN_TEST_MAX_SIZE / 2) : T::MaxRowsAtCompileTime;
|
||||
constexpr Index minCols = T::ColsAtCompileTime == Dynamic ? 1 : T::ColsAtCompileTime;
|
||||
constexpr Index maxCols = T::MaxColsAtCompileTime == Dynamic ? (EIGEN_TEST_MAX_SIZE / 2) : T::MaxColsAtCompileTime;
|
||||
|
||||
constexpr Index rowFactor = (NumTraits<Scalar>::IsComplex && !T::IsRowMajor) ? 2 : 1;
|
||||
constexpr Index colFactor = (NumTraits<Scalar>::IsComplex && T::IsRowMajor) ? 2 : 1;
|
||||
constexpr Index sizeFactor = NumTraits<Scalar>::IsComplex ? 2 : 1;
|
||||
|
||||
Index rows = internal::random<Index>(minRows, maxRows);
|
||||
Index cols = internal::random<Index>(minCols, maxCols);
|
||||
|
||||
T A(rows, cols), B, C;
|
||||
|
||||
VERIFY(A.realView().rows() == rowFactor * A.rows());
|
||||
VERIFY(A.realView().cols() == colFactor * A.cols());
|
||||
VERIFY(A.realView().size() == sizeFactor * A.size());
|
||||
|
||||
RealScalar alpha = internal::random(RealScalar(1), RealScalar(2));
|
||||
A.setRandom();
|
||||
|
||||
VERIFY_IS_APPROX(A.matrix().squaredNorm(), A.realView().matrix().squaredNorm());
|
||||
|
||||
// test re-sizing realView during assignment
|
||||
B.realView() = A.realView();
|
||||
VERIFY_IS_APPROX(A, B);
|
||||
VERIFY_IS_APPROX(A.realView(), B.realView());
|
||||
|
||||
// B = A * alpha
|
||||
for (Index r = 0; r < rows; r++) {
|
||||
for (Index c = 0; c < cols; c++) {
|
||||
B.coeffRef(r, c) = A.coeff(r, c) * Scalar(alpha);
|
||||
}
|
||||
}
|
||||
|
||||
VERIFY_IS_APPROX(B.realView(), A.realView() * alpha);
|
||||
C = A;
|
||||
C.realView() *= alpha;
|
||||
VERIFY_IS_APPROX(B, C);
|
||||
|
||||
alpha = internal::random(RealScalar(1), RealScalar(2));
|
||||
A.setRandom();
|
||||
|
||||
// B = A / alpha
|
||||
for (Index r = 0; r < rows; r++) {
|
||||
for (Index c = 0; c < cols; c++) {
|
||||
B.coeffRef(r, c) = A.coeff(r, c) / Scalar(alpha);
|
||||
}
|
||||
}
|
||||
|
||||
VERIFY_IS_APPROX(B.realView(), A.realView() / alpha);
|
||||
C = A;
|
||||
C.realView() /= alpha;
|
||||
VERIFY_IS_APPROX(B, C);
|
||||
}
|
||||
|
||||
template <typename Scalar, int Rows, int Cols, int MaxRows = Rows, int MaxCols = Cols>
|
||||
void test_realview_driver() {
|
||||
// if Rows == 1, don't test ColMajor as it is not a valid array
|
||||
using ColMajorMatrixType = Matrix<Scalar, Rows, Cols, Rows == 1 ? RowMajor : ColMajor, MaxRows, MaxCols>;
|
||||
using ColMajorArrayType = Array<Scalar, Rows, Cols, Rows == 1 ? RowMajor : ColMajor, MaxRows, MaxCols>;
|
||||
// if Cols == 1, don't test RowMajor as it is not a valid array
|
||||
using RowMajorMatrixType = Matrix<Scalar, Rows, Cols, Cols == 1 ? ColMajor : RowMajor, MaxRows, MaxCols>;
|
||||
using RowMajorArrayType = Array<Scalar, Rows, Cols, Cols == 1 ? ColMajor : RowMajor, MaxRows, MaxCols>;
|
||||
test_realview(ColMajorMatrixType());
|
||||
test_realview(ColMajorArrayType());
|
||||
test_realview(RowMajorMatrixType());
|
||||
test_realview(RowMajorArrayType());
|
||||
}
|
||||
|
||||
template <int Rows, int Cols, int MaxRows = Rows, int MaxCols = Cols>
|
||||
void test_realview_driver_complex() {
|
||||
test_realview_driver<float, Rows, Cols, MaxRows, MaxCols>();
|
||||
test_realview_driver<std::complex<float>, Rows, Cols, MaxRows, MaxCols>();
|
||||
test_realview_driver<double, Rows, Cols, MaxRows, MaxCols>();
|
||||
test_realview_driver<std::complex<double>, Rows, Cols, MaxRows, MaxCols>();
|
||||
test_realview_driver<long double, Rows, Cols, MaxRows, MaxCols>();
|
||||
test_realview_driver<std::complex<long double>, Rows, Cols, MaxRows, MaxCols>();
|
||||
}
|
||||
|
||||
EIGEN_DECLARE_TEST(realview) {
|
||||
for (int i = 0; i < g_repeat; i++) {
|
||||
CALL_SUBTEST_1((test_realview_driver_complex<Dynamic, Dynamic, Dynamic, Dynamic>()));
|
||||
CALL_SUBTEST_2((test_realview_driver_complex<Dynamic, Dynamic, 17, Dynamic>()));
|
||||
CALL_SUBTEST_3((test_realview_driver_complex<Dynamic, Dynamic, Dynamic, 19>()));
|
||||
CALL_SUBTEST_4((test_realview_driver_complex<Dynamic, Dynamic, 17, 19>()));
|
||||
CALL_SUBTEST_5((test_realview_driver_complex<17, Dynamic, 17, Dynamic>()));
|
||||
CALL_SUBTEST_6((test_realview_driver_complex<Dynamic, 19, Dynamic, 19>()));
|
||||
CALL_SUBTEST_7((test_realview_driver_complex<17, 19, 17, 19>()));
|
||||
CALL_SUBTEST_8((test_realview_driver_complex<Dynamic, 1>()));
|
||||
CALL_SUBTEST_9((test_realview_driver_complex<1, Dynamic>()));
|
||||
CALL_SUBTEST_10((test_realview_driver_complex<1, 1>()));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user