11#ifndef EIGEN_REALVIEW_H
12#define EIGEN_REALVIEW_H
15#include "./InternalHeaderCheck.h"
28struct complex_array_access : std::false_type {};
30struct complex_array_access<std::complex<T>> : std::true_type {};
32template <
typename Xpr>
33struct traits<RealView<Xpr>> :
public traits<Xpr> {
35 static constexpr int double_size(T size,
bool times_two) {
36 int size_as_int = int(size);
37 if (size_as_int == Dynamic)
return Dynamic;
38 return times_two ? (2 * size_as_int) : size_as_int;
41 using Base = traits<Xpr>;
42 using ComplexScalar =
typename Base::Scalar;
43 using Scalar =
typename NumTraits<ComplexScalar>::Real;
45 static constexpr bool ArrayAccess = complex_array_access<ComplexScalar>::value;
47 static constexpr int ActualDirectAccessBit =
48 ArrayAccess && inner_stride_at_compile_time<Xpr>::value == 1 ?
DirectAccessBit : 0;
49 static constexpr int ActualLvalueBit = !std::is_const<Xpr>::value && ArrayAccess ?
LvalueBit : 0;
51 static constexpr int FlagMask =
53 static constexpr int BaseFlags = int(evaluator<Xpr>::Flags) | int(Base::Flags);
54 static constexpr int Flags = BaseFlags & FlagMask;
55 static constexpr bool IsRowMajor = Flags &
RowMajorBit;
56 static constexpr int RowsAtCompileTime = double_size(Base::RowsAtCompileTime, !IsRowMajor);
57 static constexpr int ColsAtCompileTime = double_size(Base::ColsAtCompileTime, IsRowMajor);
58 static constexpr int SizeAtCompileTime = size_at_compile_time(RowsAtCompileTime, ColsAtCompileTime);
59 static constexpr int MaxRowsAtCompileTime = double_size(Base::MaxRowsAtCompileTime, !IsRowMajor);
60 static constexpr int MaxColsAtCompileTime = double_size(Base::MaxColsAtCompileTime, IsRowMajor);
61 static constexpr int MaxSizeAtCompileTime = size_at_compile_time(MaxRowsAtCompileTime, MaxColsAtCompileTime);
62 static constexpr int OuterStrideAtCompileTime = double_size(outer_stride_at_compile_time<Xpr>::value,
true);
63 static constexpr int InnerStrideAtCompileTime = inner_stride_at_compile_time<Xpr>::value;
66template <
typename Xpr>
67struct evaluator<RealView<Xpr>> :
private evaluator<Xpr> {
68 using BaseEvaluator = evaluator<Xpr>;
69 using XprType = RealView<Xpr>;
70 using ExpressionTraits = traits<XprType>;
71 using ComplexScalar =
typename ExpressionTraits::ComplexScalar;
72 using Scalar =
typename ExpressionTraits::Scalar;
74 static constexpr int Flags = ExpressionTraits::Flags;
75 static constexpr int CoeffReadCost = BaseEvaluator::CoeffReadCost;
76 static constexpr int Alignment = BaseEvaluator::Alignment;
77 static constexpr bool IsRowMajor = ExpressionTraits::IsRowMajor;
82 using ComplexCoeffReturnType = std::conditional_t<CoeffByReference, const ComplexScalar&, ComplexScalar>;
83 using CoeffReturnType = std::conditional_t<CoeffByReference, const Scalar&, Scalar>;
85 EIGEN_DEVICE_FUNC
explicit evaluator(XprType realView) : BaseEvaluator(realView.m_xpr) {}
87 template <
bool Enable = CoeffByReference, std::enable_if_t<!Enable,
bool> = true>
88 constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar coeff(Index row, Index col)
const {
89 Index r = IsRowMajor ? row : row / 2;
90 Index c = IsRowMajor ? col / 2 : col;
91 bool p = (IsRowMajor ? col : row) & 1;
92 ComplexScalar ccoeff = BaseEvaluator::coeff(r, c);
93 return p ? numext::imag(ccoeff) : numext::real(ccoeff);
95 template <
bool Enable = CoeffByReference, std::enable_if_t<Enable,
bool> = true>
96 constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col)
const {
97 Index r = IsRowMajor ? row : row / 2;
98 Index c = IsRowMajor ? col / 2 : col;
99 Index p = (IsRowMajor ? col : row) & 1;
100 ComplexCoeffReturnType ccoeff = BaseEvaluator::coeff(r, c);
101 return reinterpret_cast<const Scalar(&)[2]
>(ccoeff)[p];
103 template <
bool Enable = CoeffByReference, std::enable_if_t<!Enable,
bool> = true>
104 constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar coeff(Index index)
const {
105 ComplexScalar ccoeff = BaseEvaluator::coeff(index / 2);
107 return p ? numext::imag(ccoeff) : numext::real(ccoeff);
109 template <
bool Enable = CoeffByReference, std::enable_if_t<Enable,
bool> = true>
110 constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index)
const {
111 ComplexCoeffReturnType ccoeff = BaseEvaluator::coeff(index / 2);
113 return reinterpret_cast<const Scalar(&)[2]
>(ccoeff)[p];
115 constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col) {
116 Index r = IsRowMajor ? row : row / 2;
117 Index c = IsRowMajor ? col / 2 : col;
118 Index p = (IsRowMajor ? col : row) & 1;
119 ComplexScalar& ccoeffRef = BaseEvaluator::coeffRef(r, c);
120 return reinterpret_cast<Scalar(&)[2]
>(ccoeffRef)[p];
122 constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) {
123 ComplexScalar& ccoeffRef = BaseEvaluator::coeffRef(index / 2);
125 return reinterpret_cast<Scalar(&)[2]
>(ccoeffRef)[p];
132 template <
int LoadMode,
typename PacketType>
133 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index row, Index col)
const {
134 constexpr int RealPacketSize = unpacket_traits<PacketType>::size;
135 using ComplexPacket =
typename find_packet_by_size<ComplexScalar, RealPacketSize / 2>::type;
136 EIGEN_STATIC_ASSERT((find_packet_by_size<ComplexScalar, RealPacketSize / 2>::value),
137 MISSING COMPATIBLE COMPLEX PACKET TYPE)
138 Index r = IsRowMajor ? row : row / 2;
139 Index c = IsRowMajor ? col / 2 : col;
140 bool p = (IsRowMajor ? col : row) & 1;
141 ComplexPacket cresult = BaseEvaluator::template packet<LoadMode, ComplexPacket>(r, c);
142 PacketType result = preinterpret<PacketType>(cresult);
144 Scalar aux[RealPacketSize + 1];
145 pstoreu(aux, result);
146 Index lastr = IsRowMajor ? row : row + RealPacketSize - 1;
147 Index lastc = IsRowMajor ? col + RealPacketSize - 1 : col;
148 aux[RealPacketSize] = coeff(lastr, lastc);
149 result = ploadu<PacketType>(aux + 1);
154 template <
int LoadMode,
typename PacketType>
155 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index index)
const {
156 constexpr int RealPacketSize = unpacket_traits<PacketType>::size;
157 using ComplexPacket =
typename find_packet_by_size<ComplexScalar, RealPacketSize / 2>::type;
158 EIGEN_STATIC_ASSERT((find_packet_by_size<ComplexScalar, RealPacketSize / 2>::value),
159 MISSING COMPATIBLE COMPLEX PACKET TYPE)
160 ComplexPacket cresult = BaseEvaluator::template packet<LoadMode, ComplexPacket>(index / 2);
161 PacketType result = preinterpret<PacketType>(cresult);
164 Scalar aux[RealPacketSize + 1];
165 pstoreu(aux, result);
166 aux[RealPacketSize] = coeff(index + RealPacketSize - 1);
167 result = ploadu<PacketType>(aux + 1);
178 template <
int LoadMode,
typename PacketType>
179 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index row, Index col, Index begin, Index count)
const {
180 constexpr int RealPacketSize = unpacket_traits<PacketType>::size;
181 using ComplexPacket =
typename find_packet_by_size<ComplexScalar, RealPacketSize / 2>::type;
182 EIGEN_STATIC_ASSERT((find_packet_by_size<ComplexScalar, RealPacketSize / 2>::value),
183 MISSING COMPATIBLE COMPLEX PACKET TYPE)
184 Index actualBegin = numext::round_down(begin, 2);
185 Index actualEnd = numext::round_down(begin + count + 1, 2);
186 Index actualCount = actualEnd - actualBegin;
187 Index r = IsRowMajor ? row : row / 2;
188 Index c = IsRowMajor ? col / 2 : col;
189 ComplexPacket cresult =
190 BaseEvaluator::template packetSegment<LoadMode, ComplexPacket>(r, c, actualBegin / 2, actualCount / 2);
191 PacketType result = preinterpret<PacketType>(cresult);
192 bool p = (IsRowMajor ? col : row) & 1;
194 Scalar aux[RealPacketSize + 1] = {};
195 pstoreu(aux, result);
196 Index lastr = IsRowMajor ? row : row + actualEnd - 1;
197 Index lastc = IsRowMajor ? col + actualEnd - 1 : col;
198 aux[actualEnd] = coeff(lastr, lastc);
199 result = ploadu<PacketType>(aux + 1);
204 template <
int LoadMode,
typename PacketType>
205 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packetSegment(Index index, Index begin, Index count)
const {
206 constexpr int RealPacketSize = unpacket_traits<PacketType>::size;
207 using ComplexPacket =
typename find_packet_by_size<ComplexScalar, RealPacketSize / 2>::type;
208 EIGEN_STATIC_ASSERT((find_packet_by_size<ComplexScalar, RealPacketSize / 2>::value),
209 MISSING COMPATIBLE COMPLEX PACKET TYPE)
210 Index actualBegin = numext::round_down(begin, 2);
211 Index actualEnd = numext::round_down(begin + count + 1, 2);
212 Index actualCount = actualEnd - actualBegin;
213 ComplexPacket cresult =
214 BaseEvaluator::template packetSegment<LoadMode, ComplexPacket>(index / 2, actualBegin / 2, actualCount / 2);
215 PacketType result = preinterpret<PacketType>(cresult);
218 Scalar aux[RealPacketSize + 1] = {};
219 pstoreu(aux, result);
220 aux[actualEnd] = coeff(index + actualEnd - 1);
221 result = ploadu<PacketType>(aux + 1);
229template <
typename Xpr>
230class RealView :
public internal::dense_xpr_base<RealView<Xpr>>::type {
231 using ExpressionTraits = internal::traits<RealView>;
232 EIGEN_STATIC_ASSERT(NumTraits<typename Xpr::Scalar>::IsComplex, SCALAR MUST BE COMPLEX)
234 using Scalar =
typename ExpressionTraits::Scalar;
235 using Nested = RealView;
237 EIGEN_DEVICE_FUNC
explicit RealView(Xpr& xpr) : m_xpr(xpr) {}
238 EIGEN_DEVICE_FUNC
constexpr Index rows() const noexcept {
return Xpr::IsRowMajor ? m_xpr.rows() : 2 * m_xpr.rows(); }
239 EIGEN_DEVICE_FUNC
constexpr Index cols() const noexcept {
return Xpr::IsRowMajor ? 2 * m_xpr.cols() : m_xpr.cols(); }
240 EIGEN_DEVICE_FUNC
constexpr Index size() const noexcept {
return 2 * m_xpr.size(); }
241 EIGEN_DEVICE_FUNC
constexpr Index innerStride() const noexcept {
return m_xpr.innerStride(); }
242 EIGEN_DEVICE_FUNC
constexpr Index outerStride() const noexcept {
return 2 * m_xpr.outerStride(); }
243 EIGEN_DEVICE_FUNC
void resize(Index rows, Index cols) {
244 m_xpr.resize(Xpr::IsRowMajor ? rows : rows / 2, Xpr::IsRowMajor ? cols / 2 : cols);
246 EIGEN_DEVICE_FUNC
void resize(Index size) { m_xpr.resize(size / 2); }
247 using ScalarWithConstIfNotLvalue = std::conditional_t<internal::is_lvalue<Xpr>::value, Scalar,
const Scalar>;
248 EIGEN_DEVICE_FUNC ScalarWithConstIfNotLvalue* data() {
249 return reinterpret_cast<ScalarWithConstIfNotLvalue*
>(m_xpr.data());
251 EIGEN_DEVICE_FUNC
const Scalar* data()
const {
return reinterpret_cast<const Scalar*
>(m_xpr.data()); }
253 EIGEN_DEVICE_FUNC RealView(
const RealView&) =
default;
255 EIGEN_DEVICE_FUNC RealView& operator=(
const RealView& other);
257 template <
typename OtherDerived>
258 EIGEN_DEVICE_FUNC RealView& operator=(
const RealView<OtherDerived>& other);
260 template <
typename OtherDerived>
261 EIGEN_DEVICE_FUNC RealView& operator=(
const DenseBase<OtherDerived>& other);
264 friend struct internal::evaluator<RealView>;
268template <
typename Xpr>
269EIGEN_DEVICE_FUNC RealView<Xpr>& RealView<Xpr>::operator=(
const RealView& other) {
270 internal::call_assignment(*
this, other);
274template <
typename Xpr>
275template <
typename OtherDerived>
276EIGEN_DEVICE_FUNC RealView<Xpr>& RealView<Xpr>::operator=(
const RealView<OtherDerived>& other) {
277 internal::call_assignment(*
this, other);
281template <
typename Xpr>
282template <
typename OtherDerived>
284 internal::call_assignment(*
this, other.derived());
288template <
typename Derived>
290 return RealViewReturnType(derived());
293template <
typename Derived>
295 return ConstRealViewReturnType(derived());
Base class for all dense matrices, vectors, and arrays.
Definition DenseBase.h:45
RealViewReturnType realView()
Definition RealView.h:289
constexpr unsigned int ActualPacketAccessBit
Definition Constants.h:109
constexpr unsigned int PacketAccessBit
Definition Constants.h:98
constexpr unsigned int DirectAccessBit
Definition Constants.h:160
constexpr unsigned int LinearAccessBit
Definition Constants.h:134
constexpr unsigned int LvalueBit
Definition Constants.h:149
constexpr unsigned int RowMajorBit
Definition Constants.h:71