| // This file is part of Eigen, a lightweight C++ template library | |
| // for linear algebra. | |
| // | |
| // Copyright (C) 2020 The Eigen Team. | |
| // | |
| // 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_COHERENT_PAD_OP_H | |
| #define EIGEN_COHERENT_PAD_OP_H | |
| #include "./InternalHeaderCheck.h" | |
| namespace Eigen { | |
| namespace internal { | |
| // Pads a vector with zeros to a given size. | |
| template <typename XprType, int SizeAtCompileTime_> | |
| struct CoherentPadOp; | |
| template <typename XprType, int SizeAtCompileTime_> | |
| struct traits<CoherentPadOp<XprType, SizeAtCompileTime_>> : public traits<XprType> { | |
| typedef typename internal::remove_all<XprType>::type PlainXprType; | |
| typedef typename internal::ref_selector<XprType>::type XprNested; | |
| typedef typename std::remove_reference_t<XprNested> XprNested_; | |
| enum : int { | |
| IsRowMajor = traits<PlainXprType>::Flags & RowMajorBit, | |
| SizeAtCompileTime = SizeAtCompileTime_, | |
| RowsAtCompileTime = IsRowMajor ? 1 : SizeAtCompileTime, | |
| ColsAtCompileTime = IsRowMajor ? SizeAtCompileTime : 1, | |
| MaxRowsAtCompileTime = RowsAtCompileTime, | |
| MaxColsAtCompileTime = ColsAtCompileTime, | |
| Flags = traits<XprType>::Flags & ~NestByRefBit, | |
| }; | |
| }; | |
| // Pads a vector with zeros to a given size. | |
| template <typename XprType, int SizeAtCompileTime_> | |
| struct CoherentPadOp : public dense_xpr_base<CoherentPadOp<XprType, SizeAtCompileTime_>>::type { | |
| typedef typename internal::generic_xpr_base<CoherentPadOp<XprType, SizeAtCompileTime_>>::type Base; | |
| EIGEN_GENERIC_PUBLIC_INTERFACE(CoherentPadOp) | |
| using XprNested = typename traits<CoherentPadOp>::XprNested; | |
| using XprNested_ = typename traits<CoherentPadOp>::XprNested_; | |
| using NestedExpression = XprNested_; | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoherentPadOp() = delete; | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoherentPadOp(const CoherentPadOp&) = default; | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoherentPadOp(CoherentPadOp&& other) = default; | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoherentPadOp(const XprType& xpr, Index size) : m_xpr(xpr), m_size(size) { | |
| static_assert(XprNested_::IsVectorAtCompileTime, "input type must be a vector"); | |
| } | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const XprNested_& nestedExpression() const { return m_xpr; } | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index size() const { return m_size.value(); } | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rows() const { | |
| return traits<CoherentPadOp>::IsRowMajor ? Index(1) : size(); | |
| } | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index cols() const { | |
| return traits<CoherentPadOp>::IsRowMajor ? size() : Index(1); | |
| } | |
| private: | |
| XprNested m_xpr; | |
| const internal::variable_if_dynamic<Index, SizeAtCompileTime> m_size; | |
| }; | |
| // Adapted from the Replicate evaluator. | |
| template <typename ArgType, int SizeAtCompileTime> | |
| struct unary_evaluator<CoherentPadOp<ArgType, SizeAtCompileTime>> | |
| : evaluator_base<CoherentPadOp<ArgType, SizeAtCompileTime>> { | |
| typedef CoherentPadOp<ArgType, SizeAtCompileTime> XprType; | |
| typedef typename internal::remove_all_t<typename XprType::CoeffReturnType> CoeffReturnType; | |
| typedef typename internal::nested_eval<ArgType, 1>::type ArgTypeNested; | |
| typedef internal::remove_all_t<ArgTypeNested> ArgTypeNestedCleaned; | |
| enum { | |
| CoeffReadCost = evaluator<ArgTypeNestedCleaned>::CoeffReadCost, | |
| LinearAccessMask = XprType::IsVectorAtCompileTime ? LinearAccessBit : 0, | |
| Flags = evaluator<ArgTypeNestedCleaned>::Flags & (HereditaryBits | LinearAccessMask | RowMajorBit), | |
| Alignment = evaluator<ArgTypeNestedCleaned>::Alignment | |
| }; | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit unary_evaluator(const XprType& pad) | |
| : m_arg(pad.nestedExpression()), m_argImpl(m_arg), m_size(pad.nestedExpression().size()) {} | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const { | |
| EIGEN_IF_CONSTEXPR(XprType::IsRowMajor) { | |
| if (col < m_size.value()) { | |
| return m_argImpl.coeff(1, col); | |
| } | |
| } | |
| else { | |
| if (row < m_size.value()) { | |
| return m_argImpl.coeff(row, 1); | |
| } | |
| } | |
| return CoeffReturnType(0); | |
| } | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const { | |
| if (index < m_size.value()) { | |
| return m_argImpl.coeff(index); | |
| } | |
| return CoeffReturnType(0); | |
| } | |
| template <int LoadMode, typename PacketType> | |
| EIGEN_STRONG_INLINE PacketType packet(Index row, Index col) const { | |
| // AutoDiff scalar's derivative must be a vector, which is enforced by static assert. | |
| // Defer to linear access for simplicity. | |
| EIGEN_IF_CONSTEXPR(XprType::IsRowMajor) { return packet(col); } | |
| return packet(row); | |
| } | |
| template <int LoadMode, typename PacketType> | |
| EIGEN_STRONG_INLINE PacketType packet(Index index) const { | |
| constexpr int kPacketSize = unpacket_traits<PacketType>::size; | |
| if (index + kPacketSize <= m_size.value()) { | |
| return m_argImpl.template packet<LoadMode, PacketType>(index); | |
| } else if (index < m_size.value()) { | |
| // Partial packet. | |
| EIGEN_ALIGN_MAX std::remove_const_t<CoeffReturnType> values[kPacketSize]; | |
| const int partial = m_size.value() - index; | |
| for (int i = 0; i < partial && i < kPacketSize; ++i) { | |
| values[i] = m_argImpl.coeff(index + i); | |
| } | |
| for (int i = partial; i < kPacketSize; ++i) { | |
| values[i] = CoeffReturnType(0); | |
| } | |
| return pload<PacketType>(values); | |
| } | |
| return pset1<PacketType>(CoeffReturnType(0)); | |
| } | |
| protected: | |
| const ArgTypeNested m_arg; | |
| evaluator<ArgTypeNestedCleaned> m_argImpl; | |
| const variable_if_dynamic<Index, ArgTypeNestedCleaned::SizeAtCompileTime> m_size; | |
| }; | |
| } // namespace internal | |
| } // namespace Eigen | |
| #endif // EIGEN_CWISE_BINARY_OP_H |