$darkmode
Eigen  5.0.1-dev
CwiseTernaryOp.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
5 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
6 // Copyright (C) 2016 Eugene Brevdo <ebrevdo@gmail.com>
7 //
8 // This Source Code Form is subject to the terms of the Mozilla
9 // Public License v. 2.0. If a copy of the MPL was not distributed
10 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 
12 #ifndef EIGEN_CWISE_TERNARY_OP_H
13 #define EIGEN_CWISE_TERNARY_OP_H
14 
15 // IWYU pragma: private
16 #include "./InternalHeaderCheck.h"
17 
18 namespace Eigen {
19 
20 namespace internal {
21 template <typename TernaryOp, typename Arg1, typename Arg2, typename Arg3>
22 struct traits<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>> {
23  // we must not inherit from traits<Arg1> since it has
24  // the potential to cause problems with MSVC
25  typedef remove_all_t<Arg1> Ancestor;
26  typedef typename traits<Ancestor>::XprKind XprKind;
27  enum {
28  RowsAtCompileTime = traits<Ancestor>::RowsAtCompileTime,
29  ColsAtCompileTime = traits<Ancestor>::ColsAtCompileTime,
30  MaxRowsAtCompileTime = traits<Ancestor>::MaxRowsAtCompileTime,
31  MaxColsAtCompileTime = traits<Ancestor>::MaxColsAtCompileTime
32  };
33 
34  // even though we require Arg1, Arg2, and Arg3 to have the same scalar type
35  // (see CwiseTernaryOp constructor),
36  // we still want to handle the case when the result type is different.
37  typedef typename result_of<TernaryOp(const typename Arg1::Scalar&, const typename Arg2::Scalar&,
38  const typename Arg3::Scalar&)>::type Scalar;
39 
40  typedef typename internal::traits<Arg1>::StorageKind StorageKind;
41  typedef typename internal::traits<Arg1>::StorageIndex StorageIndex;
42 
43  typedef typename Arg1::Nested Arg1Nested;
44  typedef typename Arg2::Nested Arg2Nested;
45  typedef typename Arg3::Nested Arg3Nested;
46  typedef std::remove_reference_t<Arg1Nested> Arg1Nested_;
47  typedef std::remove_reference_t<Arg2Nested> Arg2Nested_;
48  typedef std::remove_reference_t<Arg3Nested> Arg3Nested_;
49  enum { Flags = Arg1Nested_::Flags & RowMajorBit };
50 };
51 } // end namespace internal
52 
53 template <typename TernaryOp, typename Arg1, typename Arg2, typename Arg3, typename StorageKind>
54 class CwiseTernaryOpImpl;
55 
83 template <typename TernaryOp, typename Arg1Type, typename Arg2Type, typename Arg3Type>
84 class CwiseTernaryOp : public CwiseTernaryOpImpl<TernaryOp, Arg1Type, Arg2Type, Arg3Type,
85  typename internal::traits<Arg1Type>::StorageKind>,
86  internal::no_assignment_operator {
87  public:
88  typedef internal::remove_all_t<Arg1Type> Arg1;
89  typedef internal::remove_all_t<Arg2Type> Arg2;
90  typedef internal::remove_all_t<Arg3Type> Arg3;
91 
92  // require the sizes to match
93  EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Arg1, Arg2)
94  EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Arg1, Arg3)
95 
96  // The index types should match
97  EIGEN_STATIC_ASSERT((internal::is_same<typename internal::traits<Arg1Type>::StorageKind,
98  typename internal::traits<Arg2Type>::StorageKind>::value),
99  STORAGE_KIND_MUST_MATCH)
100  EIGEN_STATIC_ASSERT((internal::is_same<typename internal::traits<Arg1Type>::StorageKind,
101  typename internal::traits<Arg3Type>::StorageKind>::value),
102  STORAGE_KIND_MUST_MATCH)
103 
104  typedef typename CwiseTernaryOpImpl<TernaryOp, Arg1Type, Arg2Type, Arg3Type,
105  typename internal::traits<Arg1Type>::StorageKind>::Base Base;
106  EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseTernaryOp)
107 
108  typedef typename internal::ref_selector<Arg1Type>::type Arg1Nested;
109  typedef typename internal::ref_selector<Arg2Type>::type Arg2Nested;
110  typedef typename internal::ref_selector<Arg3Type>::type Arg3Nested;
111  typedef std::remove_reference_t<Arg1Nested> Arg1Nested_;
112  typedef std::remove_reference_t<Arg2Nested> Arg2Nested_;
113  typedef std::remove_reference_t<Arg3Nested> Arg3Nested_;
114 
115  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CwiseTernaryOp(const Arg1& a1, const Arg2& a2, const Arg3& a3,
116  const TernaryOp& func = TernaryOp())
117  : m_arg1(a1), m_arg2(a2), m_arg3(a3), m_functor(func) {
118  eigen_assert(a1.rows() == a2.rows() && a1.cols() == a2.cols() && a1.rows() == a3.rows() && a1.cols() == a3.cols());
119  }
120 
121  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rows() const {
122  // return the fixed size type if available to enable compile time
123  // optimizations
124  if (internal::traits<internal::remove_all_t<Arg1Nested>>::RowsAtCompileTime == Dynamic &&
125  internal::traits<internal::remove_all_t<Arg2Nested>>::RowsAtCompileTime == Dynamic)
126  return m_arg3.rows();
127  else if (internal::traits<internal::remove_all_t<Arg1Nested>>::RowsAtCompileTime == Dynamic &&
128  internal::traits<internal::remove_all_t<Arg3Nested>>::RowsAtCompileTime == Dynamic)
129  return m_arg2.rows();
130  else
131  return m_arg1.rows();
132  }
133  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index cols() const {
134  // return the fixed size type if available to enable compile time
135  // optimizations
136  if (internal::traits<internal::remove_all_t<Arg1Nested>>::ColsAtCompileTime == Dynamic &&
137  internal::traits<internal::remove_all_t<Arg2Nested>>::ColsAtCompileTime == Dynamic)
138  return m_arg3.cols();
139  else if (internal::traits<internal::remove_all_t<Arg1Nested>>::ColsAtCompileTime == Dynamic &&
140  internal::traits<internal::remove_all_t<Arg3Nested>>::ColsAtCompileTime == Dynamic)
141  return m_arg2.cols();
142  else
143  return m_arg1.cols();
144  }
145 
147  EIGEN_DEVICE_FUNC const Arg1Nested_& arg1() const { return m_arg1; }
149  EIGEN_DEVICE_FUNC const Arg2Nested_& arg2() const { return m_arg2; }
151  EIGEN_DEVICE_FUNC const Arg3Nested_& arg3() const { return m_arg3; }
153  EIGEN_DEVICE_FUNC const TernaryOp& functor() const { return m_functor; }
154 
155  protected:
156  Arg1Nested m_arg1;
157  Arg2Nested m_arg2;
158  Arg3Nested m_arg3;
159  const TernaryOp m_functor;
160 };
161 
162 // Generic API dispatcher
163 template <typename TernaryOp, typename Arg1, typename Arg2, typename Arg3, typename StorageKind>
164 class CwiseTernaryOpImpl : public internal::generic_xpr_base<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>>::type {
165  public:
166  typedef typename internal::generic_xpr_base<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>>::type Base;
167 };
168 
169 } // end namespace Eigen
170 
171 #endif // EIGEN_CWISE_TERNARY_OP_H
const TernaryOp & functor() const
Definition: CwiseTernaryOp.h:153
const Arg3Nested_ & arg3() const
Definition: CwiseTernaryOp.h:151
const Arg2Nested_ & arg2() const
Definition: CwiseTernaryOp.h:149
Namespace containing all symbols from the Eigen library.
Definition: B01_Experimental.dox:1
const unsigned int RowMajorBit
Definition: Constants.h:70
const Arg1Nested_ & arg1() const
Definition: CwiseTernaryOp.h:147
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:82
Generic expression where a coefficient-wise ternary operator is applied to two expressions.
Definition: CwiseTernaryOp.h:84
const int Dynamic
Definition: Constants.h:25