Eigen  5.0.1
 
Loading...
Searching...
No Matches
VectorwiseOp.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2008-2019 Gael Guennebaud <gael.guennebaud@inria.fr>
5// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
6//
7// This Source Code Form is subject to the terms of the Mozilla
8// Public License v. 2.0. If a copy of the MPL was not distributed
9// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10// SPDX-License-Identifier: MPL-2.0
11
12#ifndef EIGEN_PARTIAL_REDUX_H
13#define EIGEN_PARTIAL_REDUX_H
14
15// IWYU pragma: private
16#include "./InternalHeaderCheck.h"
17
18namespace Eigen {
19
35
36template <typename MatrixType, typename MemberOp, int Direction>
38
39namespace internal {
40
41template <typename MatrixType, typename MemberOp, int Direction>
42struct traits<PartialReduxExpr<MatrixType, MemberOp, Direction>> : traits<MatrixType> {
43 using Scalar = typename MemberOp::result_type;
44 using StorageKind = typename traits<MatrixType>::StorageKind;
45 using XprKind = typename traits<MatrixType>::XprKind;
46 using InputScalar = typename MatrixType::Scalar;
47 enum {
48 RowsAtCompileTime = Direction == Vertical ? 1 : MatrixType::RowsAtCompileTime,
49 ColsAtCompileTime = Direction == Horizontal ? 1 : MatrixType::ColsAtCompileTime,
50 MaxRowsAtCompileTime = Direction == Vertical ? 1 : MatrixType::MaxRowsAtCompileTime,
51 MaxColsAtCompileTime = Direction == Horizontal ? 1 : MatrixType::MaxColsAtCompileTime,
52 Flags = RowsAtCompileTime == 1 ? RowMajorBit : 0,
53 TraversalSize = Direction == Vertical ? MatrixType::RowsAtCompileTime : MatrixType::ColsAtCompileTime
54 };
55};
56} // namespace internal
57
58template <typename MatrixType, typename MemberOp, int Direction>
59class PartialReduxExpr : public internal::dense_xpr_base<PartialReduxExpr<MatrixType, MemberOp, Direction>>::type,
60 internal::no_assignment_operator {
61 public:
62 using Base = typename internal::dense_xpr_base<PartialReduxExpr>::type;
63 EIGEN_DENSE_PUBLIC_INTERFACE(PartialReduxExpr)
64
65 EIGEN_DEVICE_FUNC explicit PartialReduxExpr(const MatrixType& mat, const MemberOp& func = MemberOp())
66 : m_matrix(mat), m_functor(func) {}
67
68 EIGEN_DEVICE_FUNC constexpr Index rows() const noexcept { return (Direction == Vertical ? 1 : m_matrix.rows()); }
69 EIGEN_DEVICE_FUNC constexpr Index cols() const noexcept { return (Direction == Horizontal ? 1 : m_matrix.cols()); }
70
71 EIGEN_DEVICE_FUNC typename MatrixType::Nested nestedExpression() const { return m_matrix; }
72
73 EIGEN_DEVICE_FUNC const MemberOp& functor() const { return m_functor; }
74
75 protected:
76 typename MatrixType::Nested m_matrix;
77 const MemberOp m_functor;
78};
79
80template <typename A, typename B>
81struct partial_redux_dummy_func;
82
83#define EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(MEMBER, COST, VECTORIZABLE, BINARYOP) \
84 template <typename ResultType, typename Scalar> \
85 struct member_##MEMBER { \
86 typedef ResultType result_type; \
87 typedef BINARYOP<Scalar, Scalar> BinaryOp; \
88 template <int Size> \
89 struct Cost : std::integral_constant<int, COST> {}; \
90 enum { Vectorizable = VECTORIZABLE }; \
91 template <typename XprType> \
92 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType operator()(const XprType& mat) const { \
93 return mat.MEMBER(); \
94 } \
95 BinaryOp binaryFunc() const { return BinaryOp(); } \
96 }
97
98#define EIGEN_MEMBER_FUNCTOR(MEMBER, COST) EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(MEMBER, COST, 0, partial_redux_dummy_func)
99
100namespace internal {
101
102EIGEN_MEMBER_FUNCTOR(norm, (Size + 5) * NumTraits<Scalar>::MulCost + (Size - 1) * NumTraits<Scalar>::AddCost);
103// These multi-pass reductions must not inherit the cheaper one-pass norm cost,
104// which could suppress materialization of an enclosing expression.
105EIGEN_MEMBER_FUNCTOR(stableNorm, Size* NumTraits<Scalar>::ReadCost + (2 * Size + 5) * NumTraits<Scalar>::MulCost +
106 (2 * Size - 1) * NumTraits<Scalar>::AddCost);
107EIGEN_MEMBER_FUNCTOR(blueNorm, Size* NumTraits<Scalar>::ReadCost + (2 * Size + 8) * NumTraits<Scalar>::MulCost +
108 (3 * Size - 1) * NumTraits<Scalar>::AddCost);
109EIGEN_MEMBER_FUNCTOR(
110 hypotNorm,
111 ((NumTraits<Scalar>::IsComplex ? 2 * Size : Size) - 1) *
112 functor_traits<
113 scalar_hypot_op<typename stable_norm_accumulator<typename NumTraits<Scalar>::Real>::type>>::Cost);
114EIGEN_MEMBER_FUNCTOR(all, (Size - 1) * NumTraits<Scalar>::AddCost);
115EIGEN_MEMBER_FUNCTOR(any, (Size - 1) * NumTraits<Scalar>::AddCost);
116EIGEN_MEMBER_FUNCTOR(count, (Size - 1) * NumTraits<Scalar>::AddCost);
117
118EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(sum, (Size - 1) * NumTraits<Scalar>::AddCost, 1, internal::scalar_sum_op);
119EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(minCoeff, (Size - 1) * NumTraits<Scalar>::AddCost, 1, internal::scalar_min_op);
120EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(maxCoeff, (Size - 1) * NumTraits<Scalar>::AddCost, 1, internal::scalar_max_op);
121EIGEN_MAKE_PARTIAL_REDUX_FUNCTOR(prod, (Size - 1) * NumTraits<Scalar>::MulCost, 1, internal::scalar_product_op);
122
123template <typename ResultType, typename Scalar>
124struct member_squaredNorm {
125 using result_type = ResultType;
126 static constexpr bool Vectorizable = false;
127 template <int Size>
128 struct Cost : std::integral_constant<int, Size * functor_traits<scalar_abs2_op<Scalar>>::Cost +
129 (Size - 1) * NumTraits<ResultType>::AddCost> {};
130 template <typename XprType>
131 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType operator()(const XprType& mat) const {
132 return mat.matrix().squaredNorm();
133 }
134};
135
136template <typename ExpressionType, int Direction,
137 bool ComplexInnerReduction =
138 NumTraits<typename ExpressionType::Scalar>::IsComplex &&
139 complex_array_access<typename ExpressionType::Scalar>::value &&
140 (Direction == (ExpressionType::IsRowMajor ? Horizontal : Vertical)) &&
141 ((int(evaluator<ExpressionType>::Flags) & (DirectAccessBit | PacketAccessBit)) != 0)>
142struct partial_squared_norm {
143 using Scalar = typename ExpressionType::Scalar;
144 using RealScalar = typename ExpressionType::RealScalar;
145 using Type = PartialReduxExpr<const CwiseUnaryOp<scalar_abs2_op<Scalar>, const ExpressionType>,
146 member_sum<RealScalar, RealScalar>, Direction>;
147 EIGEN_DEVICE_FUNC static Type run(const ExpressionType& matrix) { return Type(matrix.cwiseAbs2()); }
148};
149
150// Keep scalars without array-oriented access and scalar-only expressions on abs2(): realView()
151// copies/evaluates their coefficients twice. Packet expressions still evaluate scalar tails
152// and reductions shorter than one packet twice.
153template <typename ExpressionType, int Direction>
154struct partial_squared_norm<ExpressionType, Direction, true> {
155 using Type =
156 PartialReduxExpr<const ExpressionType,
157 member_squaredNorm<typename ExpressionType::RealScalar, typename ExpressionType::Scalar>,
158 Direction>;
159 EIGEN_DEVICE_FUNC static Type run(const ExpressionType& matrix) { return Type(matrix); }
160};
161
162template <int p, typename ResultType, typename Scalar>
163struct member_lpnorm {
164 using result_type = ResultType;
165 enum { Vectorizable = 0 };
166 template <int Size>
167 struct Cost
168 : std::integral_constant<int, (Size + 5) * NumTraits<Scalar>::MulCost + (Size - 1) * NumTraits<Scalar>::AddCost> {
169 };
170 EIGEN_DEVICE_FUNC member_lpnorm() = default;
171 template <typename XprType>
172 EIGEN_DEVICE_FUNC inline ResultType operator()(const XprType& mat) const {
173 return mat.template lpNorm<p>();
174 }
175};
176
177template <typename BinaryOpT, typename Scalar>
178struct member_redux {
179 using BinaryOp = BinaryOpT;
180 using result_type = typename result_of<BinaryOp(const Scalar&, const Scalar&)>::type;
181
182 enum { Vectorizable = functor_traits<BinaryOp>::PacketAccess };
183 template <int Size>
184 struct Cost : std::integral_constant<int, (Size - 1) * functor_traits<BinaryOp>::Cost> {};
185 EIGEN_DEVICE_FUNC explicit member_redux(const BinaryOp func) : m_functor(func) {}
186 template <typename Derived>
187 EIGEN_DEVICE_FUNC inline result_type operator()(const DenseBase<Derived>& mat) const {
188 return mat.redux(m_functor);
189 }
190 const BinaryOp& binaryFunc() const { return m_functor; }
191 const BinaryOp m_functor;
192};
193
194template <typename Scalar>
195struct scalar_replace_zero_with_one_op {
196 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const Scalar& x) const {
197 return numext::is_exactly_zero(x) ? Scalar(1) : x;
198 }
199 template <typename Packet>
200 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& x) const {
201 return pselect(pcmp_eq(x, pzero(x)), pset1<Packet>(Scalar(1)), x);
202 }
203};
204template <typename Scalar>
205struct functor_traits<scalar_replace_zero_with_one_op<Scalar>> {
206 enum { Cost = 1, PacketAccess = packet_traits<Scalar>::HasCmp };
207};
208
209} // namespace internal
210
248template <typename ExpressionType, int Direction>
249class VectorwiseOp {
250 public:
251 using Scalar = typename ExpressionType::Scalar;
252 using RealScalar = typename ExpressionType::RealScalar;
253 using Index = Eigen::Index;
254 using ExpressionTypeNested = typename internal::ref_selector<ExpressionType>::non_const_type;
255 using ExpressionTypeNestedCleaned = internal::remove_all_t<ExpressionTypeNested>;
256
257 template <template <typename OutScalar, typename InputScalar> class Functor, typename ReturnScalar = Scalar>
258 struct ReturnType {
260 };
261
262 template <typename BinaryOp>
263 struct ReduxReturnType {
265 };
266
267 enum { isVertical = (Direction == Vertical) ? 1 : 0, isHorizontal = (Direction == Horizontal) ? 1 : 0 };
268
269 protected:
270 template <typename OtherDerived>
271 struct ExtendedType {
272 using Type = Replicate<OtherDerived, isVertical ? 1 : ExpressionType::RowsAtCompileTime,
273 isHorizontal ? 1 : ExpressionType::ColsAtCompileTime>;
274 };
275
278 template <typename OtherDerived>
279 EIGEN_DEVICE_FUNC typename ExtendedType<OtherDerived>::Type extendedTo(const DenseBase<OtherDerived>& other) const {
280 EIGEN_STATIC_ASSERT(internal::check_implication(isVertical, OtherDerived::MaxColsAtCompileTime == 1),
281 YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED)
282 EIGEN_STATIC_ASSERT(internal::check_implication(isHorizontal, OtherDerived::MaxRowsAtCompileTime == 1),
283 YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED)
284 return typename ExtendedType<OtherDerived>::Type(other.derived(), isVertical ? 1 : m_matrix.rows(),
285 isHorizontal ? 1 : m_matrix.cols());
286 }
287
288 template <typename OtherDerived>
289 struct OppositeExtendedType {
290 using Type = Replicate<OtherDerived, isHorizontal ? 1 : ExpressionType::RowsAtCompileTime,
291 isVertical ? 1 : ExpressionType::ColsAtCompileTime>;
292 };
293
296 template <typename OtherDerived>
297 EIGEN_DEVICE_FUNC typename OppositeExtendedType<OtherDerived>::Type extendedToOpposite(
298 const DenseBase<OtherDerived>& other) const {
299 EIGEN_STATIC_ASSERT(internal::check_implication(isHorizontal, OtherDerived::MaxColsAtCompileTime == 1),
300 YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED)
301 EIGEN_STATIC_ASSERT(internal::check_implication(isVertical, OtherDerived::MaxRowsAtCompileTime == 1),
302 YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED)
303 return typename OppositeExtendedType<OtherDerived>::Type(other.derived(), isHorizontal ? 1 : m_matrix.rows(),
304 isVertical ? 1 : m_matrix.cols());
305 }
306
307 public:
308 EIGEN_DEVICE_FUNC explicit inline VectorwiseOp(ExpressionType& matrix) : m_matrix(matrix) {}
309
311 EIGEN_DEVICE_FUNC inline const ExpressionType& _expression() const { return m_matrix; }
312
313#ifdef EIGEN_PARSED_BY_DOXYGEN
317 random_access_iterator_type iterator;
319 random_access_iterator_type const_iterator;
320#else
321 using iterator = internal::subvector_stl_iterator<ExpressionType, DirectionType(Direction)>;
322 using const_iterator = internal::subvector_stl_iterator<const ExpressionType, DirectionType(Direction)>;
323 using reverse_iterator = internal::subvector_stl_reverse_iterator<ExpressionType, DirectionType(Direction)>;
324 using const_reverse_iterator =
325 internal::subvector_stl_reverse_iterator<const ExpressionType, DirectionType(Direction)>;
326#endif
327
331 iterator begin() { return iterator(m_matrix, 0); }
333 const_iterator begin() const { return const_iterator(m_matrix, 0); }
335 const_iterator cbegin() const { return const_iterator(m_matrix, 0); }
336
340 reverse_iterator rbegin() {
341 return reverse_iterator(m_matrix, m_matrix.template subVectors<DirectionType(Direction)>() - 1);
342 }
343
344 const_reverse_iterator rbegin() const {
345 return const_reverse_iterator(m_matrix, m_matrix.template subVectors<DirectionType(Direction)>() - 1);
346 }
347
348 const_reverse_iterator crbegin() const {
349 return const_reverse_iterator(m_matrix, m_matrix.template subVectors<DirectionType(Direction)>() - 1);
350 }
351
355 iterator end() { return iterator(m_matrix, m_matrix.template subVectors<DirectionType(Direction)>()); }
358 return const_iterator(m_matrix, m_matrix.template subVectors<DirectionType(Direction)>());
359 }
360
362 return const_iterator(m_matrix, m_matrix.template subVectors<DirectionType(Direction)>());
363 }
364
368 reverse_iterator rend() { return reverse_iterator(m_matrix, -1); }
370 const_reverse_iterator rend() const { return const_reverse_iterator(m_matrix, -1); }
372 const_reverse_iterator crend() const { return const_reverse_iterator(m_matrix, -1); }
373
384 template <typename BinaryOp>
385 EIGEN_DEVICE_FUNC const typename ReduxReturnType<BinaryOp>::Type redux(const BinaryOp& func = BinaryOp()) const {
386 eigen_assert(redux_length() > 0 && "you are using an empty matrix");
387 return typename ReduxReturnType<BinaryOp>::Type(_expression(), internal::member_redux<BinaryOp, Scalar>(func));
388 }
389
390 using MinCoeffReturnType = typename ReturnType<Eigen::internal::member_minCoeff>::Type;
391 using MaxCoeffReturnType = typename ReturnType<Eigen::internal::member_maxCoeff>::Type;
392 using SquaredNormReturnType = typename internal::partial_squared_norm<ExpressionTypeNestedCleaned, Direction>::Type;
393 using NormReturnType = CwiseUnaryOp<internal::scalar_sqrt_op<RealScalar>, const SquaredNormReturnType>;
394 using BlueNormReturnType = typename ReturnType<Eigen::internal::member_blueNorm, RealScalar>::Type;
395 using StableNormReturnType = typename ReturnType<Eigen::internal::member_stableNorm, RealScalar>::Type;
396 using HypotNormReturnType = typename ReturnType<Eigen::internal::member_hypotNorm, RealScalar>::Type;
397 using SumReturnType = typename ReturnType<Eigen::internal::member_sum>::Type;
398 using MeanReturnType = EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(SumReturnType, Scalar, internal::scalar_quotient_op);
399 using AllReturnType = typename ReturnType<Eigen::internal::member_all, bool>::Type;
400 using AnyReturnType = typename ReturnType<Eigen::internal::member_any, bool>::Type;
402 using ProdReturnType = typename ReturnType<Eigen::internal::member_prod>::Type;
403 using ConstReverseReturnType = Reverse<const ExpressionType, Direction>;
404 using ReverseReturnType = Reverse<ExpressionType, Direction>;
405
406 template <int p>
407 struct LpNormReturnType {
409 };
410
423 EIGEN_DEVICE_FUNC const MinCoeffReturnType minCoeff() const {
424 eigen_assert(redux_length() > 0 && "you are using an empty matrix");
425 return MinCoeffReturnType(_expression());
426 }
427
440 EIGEN_DEVICE_FUNC const MaxCoeffReturnType maxCoeff() const {
441 eigen_assert(redux_length() > 0 && "you are using an empty matrix");
442 return MaxCoeffReturnType(_expression());
443 }
444
453 EIGEN_DEVICE_FUNC const SquaredNormReturnType squaredNorm() const {
454 return internal::partial_squared_norm<ExpressionTypeNestedCleaned, Direction>::run(m_matrix);
455 }
456
465 EIGEN_DEVICE_FUNC const NormReturnType norm() const { return NormReturnType(squaredNorm()); }
466
474 * \sa DenseBase::norm() */
475 template <int p>
476 EIGEN_DEVICE_FUNC const typename LpNormReturnType<p>::Type lpNorm() const {
477 return typename LpNormReturnType<p>::Type(_expression());
478 }
479
483 * This is a vector with real entries, even if the original matrix has complex entries.
484 *
485 * \sa DenseBase::blueNorm() */
486 EIGEN_DEVICE_FUNC const BlueNormReturnType blueNorm() const { return BlueNormReturnType(_expression()); }
487
494 EIGEN_DEVICE_FUNC const StableNormReturnType stableNorm() const { return StableNormReturnType(_expression()); }
495
502 EIGEN_DEVICE_FUNC const HypotNormReturnType hypotNorm() const { return HypotNormReturnType(_expression()); }
503
511 EIGEN_DEVICE_FUNC const SumReturnType sum() const { return SumReturnType(_expression()); }
512
517 EIGEN_DEVICE_FUNC const MeanReturnType mean() const {
518 return sum() / Scalar(Direction == Vertical ? m_matrix.rows() : m_matrix.cols());
519 }
520
526 EIGEN_DEVICE_FUNC const AllReturnType all() const { return AllReturnType(_expression()); }
527
533 EIGEN_DEVICE_FUNC const AnyReturnType any() const { return AnyReturnType(_expression()); }
534
544 EIGEN_DEVICE_FUNC const CountReturnType count() const { return CountReturnType(_expression()); }
545
553 EIGEN_DEVICE_FUNC const ProdReturnType prod() const { return ProdReturnType(_expression()); }
554
562 EIGEN_DEVICE_FUNC const ConstReverseReturnType reverse() const { return ConstReverseReturnType(_expression()); }
563
568 EIGEN_DEVICE_FUNC ReverseReturnType reverse() { return ReverseReturnType(_expression()); }
569
570 using ReplicateReturnType = Replicate<ExpressionType, (isVertical ? Dynamic : 1), (isHorizontal ? Dynamic : 1)>;
571 EIGEN_DEVICE_FUNC const ReplicateReturnType replicate(Index factor) const;
572
582 // NOTE implemented here because of sunstudio's compilation errors
583 // isVertical*Factor+isHorizontal instead of (isVertical?Factor:1) to handle CUDA bug with ternary operator
584 template <int Factor>
585 const Replicate<ExpressionType, isVertical * Factor + isHorizontal,
586 isHorizontal * Factor + isVertical> EIGEN_DEVICE_FUNC
587 replicate(Index factor = Factor) const {
589 _expression(), isVertical ? factor : 1, isHorizontal ? factor : 1);
590 }
591
601 template <typename NFactorType>
602 EIGEN_DEVICE_FUNC const
604 isHorizontal * internal::get_fixed_value<NFactorType>::value + isVertical>
605 replicate(NFactorType nFactor) const {
606 return replicate<internal::get_fixed_value<NFactorType>::value>(internal::get_runtime_value(nFactor));
607 }
608
610
611 // The broadcast (compound-)assignments below bind the rhs through
612 // `nested_eval<.., Dynamic>` so expressions like `colwise().sum()` are
613 // materialized once; otherwise an aliased reduction would be recomputed
614 // against partially-updated coefficients (issue #1731).
615
617 template <typename OtherDerived>
618 EIGEN_DEVICE_FUNC ExpressionType& operator=(const DenseBase<OtherDerived>& other) {
619 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
620 EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
621 // eigen_assert((m_matrix.isNull()) == (other.isNull())); FIXME
622 typename internal::nested_eval<OtherDerived, Dynamic>::type other_eval(other.derived());
623 return m_matrix = extendedTo(other_eval);
624 }
625
627 template <typename OtherDerived>
628 EIGEN_DEVICE_FUNC ExpressionType& operator+=(const DenseBase<OtherDerived>& other) {
629 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
630 EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
631 typename internal::nested_eval<OtherDerived, Dynamic>::type other_eval(other.derived());
632 return m_matrix += extendedTo(other_eval);
633 }
634
636 template <typename OtherDerived>
637 EIGEN_DEVICE_FUNC ExpressionType& operator-=(const DenseBase<OtherDerived>& other) {
638 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
639 EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
640 typename internal::nested_eval<OtherDerived, Dynamic>::type other_eval(other.derived());
641 return m_matrix -= extendedTo(other_eval);
642 }
643
645 template <typename OtherDerived>
646 EIGEN_DEVICE_FUNC ExpressionType& operator*=(const DenseBase<OtherDerived>& other) {
647 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
648 EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
649 EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
650 typename internal::nested_eval<OtherDerived, Dynamic>::type other_eval(other.derived());
651 m_matrix *= extendedTo(other_eval);
652 return m_matrix;
653 }
654
656 template <typename OtherDerived>
657 EIGEN_DEVICE_FUNC ExpressionType& operator/=(const DenseBase<OtherDerived>& other) {
658 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
659 EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
660 EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
661 typename internal::nested_eval<OtherDerived, Dynamic>::type other_eval(other.derived());
662 m_matrix /= extendedTo(other_eval);
663 return m_matrix;
664 }
665
667 template <typename OtherDerived>
668 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
670 const typename ExtendedType<OtherDerived>::Type>
671 operator+(const DenseBase<OtherDerived>& other) const {
672 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
673 EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
674 return m_matrix + extendedTo(other.derived());
675 }
676
678 template <typename OtherDerived>
679 friend EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
681 const typename ExtendedType<OtherDerived>::Type, const ExpressionTypeNestedCleaned>
682 operator+(const DenseBase<OtherDerived>& other, const VectorwiseOp& xpr) {
683 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
684 EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
686 const typename ExtendedType<OtherDerived>::Type, const ExpressionTypeNestedCleaned>(
687 xpr.extendedTo(other.derived()), xpr._expression());
688 }
689
691 template <typename OtherDerived>
693 const ExpressionTypeNestedCleaned, const typename ExtendedType<OtherDerived>::Type>
694 operator-(const DenseBase<OtherDerived>& other) const {
695 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
696 EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
697 return m_matrix - extendedTo(other.derived());
698 }
699
701 template <typename OtherDerived>
702 friend EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
704 const typename ExtendedType<OtherDerived>::Type, const ExpressionTypeNestedCleaned>
705 operator-(const DenseBase<OtherDerived>& other, const VectorwiseOp& xpr) {
706 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
707 EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
709 const typename ExtendedType<OtherDerived>::Type, const ExpressionTypeNestedCleaned>(
710 xpr.extendedTo(other.derived()), xpr._expression());
711 }
712
715 template <typename OtherDerived>
717 const ExpressionTypeNestedCleaned, const typename ExtendedType<OtherDerived>::Type>
718 operator*(const DenseBase<OtherDerived>& other) const {
719 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
720 EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
721 EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
722 return m_matrix * extendedTo(other.derived());
723 }
724
726 template <typename OtherDerived>
727 friend EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
729 const typename ExtendedType<OtherDerived>::Type, const ExpressionTypeNestedCleaned>
730 operator*(const DenseBase<OtherDerived>& other, const VectorwiseOp& xpr) {
731 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
732 EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
733 EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
735 const typename ExtendedType<OtherDerived>::Type, const ExpressionTypeNestedCleaned>(
736 xpr.extendedTo(other.derived()), xpr._expression());
737 }
738
741 template <typename OtherDerived>
743 const ExpressionTypeNestedCleaned, const typename ExtendedType<OtherDerived>::Type>
744 operator/(const DenseBase<OtherDerived>& other) const {
745 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
746 EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
747 EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
748 return m_matrix / extendedTo(other.derived());
749 }
750
752 template <typename OtherDerived>
753 friend EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
755 const typename ExtendedType<OtherDerived>::Type, const ExpressionTypeNestedCleaned>
756 operator/(const DenseBase<OtherDerived>& other, const VectorwiseOp& xpr) {
757 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
758 EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
759 EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
761 const typename ExtendedType<OtherDerived>::Type, const ExpressionTypeNestedCleaned>(
762 xpr.extendedTo(other.derived()), xpr._expression());
763 }
764
766 template <typename CustomBinaryOp, typename OtherDerived>
767 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const
769 binaryExpr(const DenseBase<OtherDerived>& other, const CustomBinaryOp& func = CustomBinaryOp()) const {
770 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
771 EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
772 return CwiseBinaryOp<CustomBinaryOp, const ExpressionTypeNestedCleaned,
773 const typename ExtendedType<OtherDerived>::Type>(_expression(), extendedTo(other.derived()),
774 func);
775 }
776
778 template <int NaNPropagation = PropagateFast, typename OtherDerived>
779 EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE const
781 const ExpressionTypeNestedCleaned, const typename ExtendedType<OtherDerived>::Type>
782 cwiseMin(const DenseBase<OtherDerived>& other) const {
783 return binaryExpr(other, internal::scalar_min_op<Scalar, typename OtherDerived::Scalar, NaNPropagation>());
784 }
785
787 template <int NaNPropagation = PropagateFast>
788 EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE const
790 const typename ExpressionTypeNestedCleaned::ConstantReturnType>
791 cwiseMin(const Scalar& other) const {
792 return CwiseBinaryOp<internal::scalar_min_op<Scalar, Scalar, NaNPropagation>, const ExpressionTypeNestedCleaned,
793 const typename ExpressionTypeNestedCleaned::ConstantReturnType>(
794 _expression(), ExpressionTypeNestedCleaned::Constant(m_matrix.rows(), m_matrix.cols(), other));
795 }
796
798 template <int NaNPropagation = PropagateFast, typename OtherDerived>
799 EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE const
801 const ExpressionTypeNestedCleaned, const typename ExtendedType<OtherDerived>::Type>
802 cwiseMax(const DenseBase<OtherDerived>& other) const {
803 return binaryExpr(other, internal::scalar_max_op<Scalar, typename OtherDerived::Scalar, NaNPropagation>());
804 }
805
807 template <int NaNPropagation = PropagateFast>
808 EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE const
810 const typename ExpressionTypeNestedCleaned::ConstantReturnType>
811 cwiseMax(const Scalar& other) const {
812 return CwiseBinaryOp<internal::scalar_max_op<Scalar, Scalar, NaNPropagation>, const ExpressionTypeNestedCleaned,
813 const typename ExpressionTypeNestedCleaned::ConstantReturnType>(
814 _expression(), ExpressionTypeNestedCleaned::Constant(m_matrix.rows(), m_matrix.cols(), other));
815 }
816
817 using Normalized_NonzeroNormType =
819 using NormalizedReturnType = CwiseBinaryOp<internal::scalar_quotient_op<Scalar>, const ExpressionTypeNestedCleaned,
820 const typename OppositeExtendedType<Normalized_NonzeroNormType>::Type>;
821
830 EIGEN_DEVICE_FUNC NormalizedReturnType normalized() const {
831 return m_matrix.cwiseQuotient(extendedToOpposite(Normalized_NonzeroNormType(this->norm())));
832 }
833
840 EIGEN_DEVICE_FUNC void normalize() { m_matrix = this->normalized(); }
841
842 EIGEN_DEVICE_FUNC inline void reverseInPlace();
843
845
846 using HomogeneousReturnType = Homogeneous<ExpressionType, Direction>;
847 EIGEN_DEVICE_FUNC HomogeneousReturnType homogeneous() const;
848
849 using CrossReturnType = typename ExpressionType::PlainObject;
850 template <typename OtherDerived>
851 EIGEN_DEVICE_FUNC const CrossReturnType cross(const MatrixBase<OtherDerived>& other) const;
852
853 enum {
854 HNormalized_Size = Direction == Vertical ? internal::traits<ExpressionType>::RowsAtCompileTime
855 : internal::traits<ExpressionType>::ColsAtCompileTime,
856 HNormalized_SizeMinusOne = HNormalized_Size == Dynamic ? Dynamic : HNormalized_Size - 1
857 };
858 using HNormalized_Block = Block<const ExpressionType,
859 Direction == Vertical ? int(HNormalized_SizeMinusOne)
860 : int(internal::traits<ExpressionType>::RowsAtCompileTime),
861 Direction == Horizontal ? int(HNormalized_SizeMinusOne)
862 : int(internal::traits<ExpressionType>::ColsAtCompileTime)>;
863 using HNormalized_Factors =
864 Block<const ExpressionType, Direction == Vertical ? 1 : int(internal::traits<ExpressionType>::RowsAtCompileTime),
865 Direction == Horizontal ? 1 : int(internal::traits<ExpressionType>::ColsAtCompileTime)>;
866 using HNormalizedReturnType =
868 const HNormalized_Block,
869 const Replicate<HNormalized_Factors, Direction == Vertical ? HNormalized_SizeMinusOne : 1,
870 Direction == Horizontal ? HNormalized_SizeMinusOne : 1>>;
871
872 EIGEN_DEVICE_FUNC const HNormalizedReturnType hnormalized() const;
873
874#ifdef EIGEN_VECTORWISEOP_PLUGIN
875#include EIGEN_VECTORWISEOP_PLUGIN
876#endif
877
878 protected:
879 EIGEN_DEVICE_FUNC Index redux_length() const { return Direction == Vertical ? m_matrix.rows() : m_matrix.cols(); }
880 ExpressionTypeNested m_matrix;
881};
882
883// const colwise moved to DenseBase.h due to CUDA compiler bug
884
889template <typename Derived>
890EIGEN_DEVICE_FUNC inline typename DenseBase<Derived>::ColwiseReturnType DenseBase<Derived>::colwise() {
891 return ColwiseReturnType(derived());
892}
893
894// const rowwise moved to DenseBase.h due to CUDA compiler bug
895
900template <typename Derived>
901EIGEN_DEVICE_FUNC inline typename DenseBase<Derived>::RowwiseReturnType DenseBase<Derived>::rowwise() {
902 return RowwiseReturnType(derived());
903}
904
905} // end namespace Eigen
906
907#endif // EIGEN_PARTIAL_REDUX_H
Expression of a fixed-size or dynamic-size block.
Definition Block.h:111
Generic expression where a coefficient-wise binary operator is applied to two expressions.
Definition CwiseBinaryOp.h:80
Generic expression where a coefficient-wise unary operator is applied to an expression.
Definition CwiseUnaryOp.h:55
Base class for all dense matrices, vectors, and arrays.
Definition DenseBase.h:45
ConstColwiseReturnType colwise() const
Definition DenseBase.h:482
ConstRowwiseReturnType rowwise() const
Definition DenseBase.h:472
Expression of one (or a set of) homogeneous vector(s)
Definition Homogeneous.h:63
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:53
Generic expression of a partially reduxed matrix.
Definition VectorwiseOp.h:60
Expression of the multiple replication of a matrix or vector.
Definition Replicate.h:65
Expression of the reverse of a vector or matrix.
Definition Reverse.h:66
const HypotNormReturnType hypotNorm() const
Definition VectorwiseOp.h:502
const SquaredNormReturnType squaredNorm() const
Definition VectorwiseOp.h:453
const Replicate< ExpressionType, isVertical *Factor+isHorizontal, isHorizontal *Factor+isVertical > replicate(Index factor=Factor) const
Definition VectorwiseOp.h:587
const ProdReturnType prod() const
Definition VectorwiseOp.h:553
CwiseBinaryOp< internal::scalar_difference_op< Scalar, typename OtherDerived::Scalar >, const ExpressionTypeNestedCleaned, const typename ExtendedType< OtherDerived >::Type > operator-(const DenseBase< OtherDerived > &other) const
Definition VectorwiseOp.h:694
NormalizedReturnType normalized() const
Definition VectorwiseOp.h:830
friend CwiseBinaryOp< internal::scalar_product_op< typename OtherDerived::Scalar, Scalar >, const typename ExtendedType< OtherDerived >::Type, const ExpressionTypeNestedCleaned > operator*(const DenseBase< OtherDerived > &other, const VectorwiseOp &xpr)
Definition VectorwiseOp.h:730
const_reverse_iterator crend() const
Definition VectorwiseOp.h:372
const Replicate< ExpressionType, isVertical *internal::get_fixed_value< NFactorType >::value+isHorizontal, isHorizontal *internal::get_fixed_value< NFactorType >::value+isVertical > replicate(NFactorType nFactor) const
Definition VectorwiseOp.h:605
constexpr const CwiseBinaryOp< internal::scalar_min_op< Scalar, typename OtherDerived::Scalar, NaNPropagation >, const ExpressionTypeNestedCleaned, const typename ExtendedType< OtherDerived >::Type > cwiseMin(const DenseBase< OtherDerived > &other) const
Definition VectorwiseOp.h:782
friend CwiseBinaryOp< internal::scalar_sum_op< typename OtherDerived::Scalar, Scalar >, const typename ExtendedType< OtherDerived >::Type, const ExpressionTypeNestedCleaned > operator+(const DenseBase< OtherDerived > &other, const VectorwiseOp &xpr)
Definition VectorwiseOp.h:682
ExpressionType & operator-=(const DenseBase< OtherDerived > &other)
Definition VectorwiseOp.h:637
CwiseBinaryOp< internal::scalar_sum_op< Scalar, typename OtherDerived::Scalar >, const ExpressionTypeNestedCleaned, const typename ExtendedType< OtherDerived >::Type > operator+(const DenseBase< OtherDerived > &other) const
Definition VectorwiseOp.h:671
const BlueNormReturnType blueNorm() const
Definition VectorwiseOp.h:486
ExpressionType & operator/=(const DenseBase< OtherDerived > &other)
Definition VectorwiseOp.h:657
const_iterator cend() const
Definition VectorwiseOp.h:361
random_access_iterator_type const_iterator
Definition VectorwiseOp.h:319
const CountReturnType count() const
Definition VectorwiseOp.h:544
const ReplicateReturnType replicate(Index factor) const
Definition Replicate.h:125
const MaxCoeffReturnType maxCoeff() const
Definition VectorwiseOp.h:440
const SumReturnType sum() const
Definition VectorwiseOp.h:511
ExpressionType & operator*=(const DenseBase< OtherDerived > &other)
Definition VectorwiseOp.h:646
const_iterator cbegin() const
Definition VectorwiseOp.h:335
const MinCoeffReturnType minCoeff() const
Definition VectorwiseOp.h:423
constexpr const CwiseBinaryOp< internal::scalar_max_op< Scalar, typename OtherDerived::Scalar, NaNPropagation >, const ExpressionTypeNestedCleaned, const typename ExtendedType< OtherDerived >::Type > cwiseMax(const DenseBase< OtherDerived > &other) const
Definition VectorwiseOp.h:802
CwiseBinaryOp< internal::scalar_quotient_op< Scalar, typename OtherDerived::Scalar >, const ExpressionTypeNestedCleaned, const typename ExtendedType< OtherDerived >::Type > operator/(const DenseBase< OtherDerived > &other) const
Definition VectorwiseOp.h:744
reverse_iterator rbegin()
Definition VectorwiseOp.h:340
const AnyReturnType any() const
Definition VectorwiseOp.h:533
const AllReturnType all() const
Definition VectorwiseOp.h:526
iterator end()
Definition VectorwiseOp.h:355
random_access_iterator_type iterator
Definition VectorwiseOp.h:317
const_reverse_iterator rbegin() const
Definition VectorwiseOp.h:344
reverse_iterator rend()
Definition VectorwiseOp.h:368
const MeanReturnType mean() const
Definition VectorwiseOp.h:517
const_iterator begin() const
Definition VectorwiseOp.h:333
friend CwiseBinaryOp< internal::scalar_quotient_op< typename OtherDerived::Scalar, Scalar >, const typename ExtendedType< OtherDerived >::Type, const ExpressionTypeNestedCleaned > operator/(const DenseBase< OtherDerived > &other, const VectorwiseOp &xpr)
Definition VectorwiseOp.h:756
ExpressionType & operator=(const DenseBase< OtherDerived > &other)
Definition VectorwiseOp.h:618
ReverseReturnType reverse()
Definition VectorwiseOp.h:568
void reverseInPlace()
Definition Reverse.h:197
iterator begin()
Definition VectorwiseOp.h:331
ExpressionType & operator+=(const DenseBase< OtherDerived > &other)
Definition VectorwiseOp.h:628
Eigen::Index Index
Definition VectorwiseOp.h:253
const_iterator end() const
Definition VectorwiseOp.h:357
friend CwiseBinaryOp< internal::scalar_difference_op< typename OtherDerived::Scalar, Scalar >, const typename ExtendedType< OtherDerived >::Type, const ExpressionTypeNestedCleaned > operator-(const DenseBase< OtherDerived > &other, const VectorwiseOp &xpr)
Definition VectorwiseOp.h:705
void normalize()
Definition VectorwiseOp.h:840
const StableNormReturnType stableNorm() const
Definition VectorwiseOp.h:494
const LpNormReturnType< p >::Type lpNorm() const
Definition VectorwiseOp.h:476
const CwiseBinaryOp< CustomBinaryOp, const ExpressionTypeNestedCleaned, const typename ExtendedType< OtherDerived >::Type > binaryExpr(const DenseBase< OtherDerived > &other, const CustomBinaryOp &func=CustomBinaryOp()) const
Definition VectorwiseOp.h:769
constexpr const CwiseBinaryOp< internal::scalar_min_op< Scalar, Scalar, NaNPropagation >, const ExpressionTypeNestedCleaned, const typename ExpressionTypeNestedCleaned::ConstantReturnType > cwiseMin(const Scalar &other) const
Definition VectorwiseOp.h:791
const ConstReverseReturnType reverse() const
Definition VectorwiseOp.h:562
const_reverse_iterator crbegin() const
Definition VectorwiseOp.h:348
CwiseBinaryOp< internal::scalar_product_op< Scalar, typename OtherDerived::Scalar >, const ExpressionTypeNestedCleaned, const typename ExtendedType< OtherDerived >::Type > operator*(const DenseBase< OtherDerived > &other) const
Definition VectorwiseOp.h:718
const NormReturnType norm() const
Definition VectorwiseOp.h:465
const ReduxReturnType< BinaryOp >::Type redux(const BinaryOp &func=BinaryOp()) const
Definition VectorwiseOp.h:385
constexpr const CwiseBinaryOp< internal::scalar_max_op< Scalar, Scalar, NaNPropagation >, const ExpressionTypeNestedCleaned, const typename ExpressionTypeNestedCleaned::ConstantReturnType > cwiseMax(const Scalar &other) const
Definition VectorwiseOp.h:811
const_reverse_iterator rend() const
Definition VectorwiseOp.h:370
const HNormalizedReturnType hnormalized() const
column or row-wise homogeneous normalization
Definition Homogeneous.h:190
const CrossReturnType cross(const MatrixBase< OtherDerived > &other) const
Definition OrthoMethods.h:150
HomogeneousReturnType homogeneous() const
Definition Homogeneous.h:142
DirectionType
Definition Constants.h:264
@ Horizontal
Definition Constants.h:270
@ Vertical
Definition Constants.h:267
constexpr unsigned int PacketAccessBit
Definition Constants.h:98
constexpr unsigned int DirectAccessBit
Definition Constants.h:160
constexpr unsigned int RowMajorBit
Definition Constants.h:71