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
15namespace Eigen {
16
17namespace internal {
18template <typename TernaryOp, typename Arg1, typename Arg2, typename Arg3>
19struct traits<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> > {
20 // we must not inherit from traits<Arg1> since it has
21 // the potential to cause problems with MSVC
22 typedef typename remove_all<Arg1>::type Ancestor;
23 typedef typename traits<Ancestor>::XprKind XprKind;
24 enum {
25 RowsAtCompileTime = traits<Ancestor>::RowsAtCompileTime,
26 ColsAtCompileTime = traits<Ancestor>::ColsAtCompileTime,
27 MaxRowsAtCompileTime = traits<Ancestor>::MaxRowsAtCompileTime,
28 MaxColsAtCompileTime = traits<Ancestor>::MaxColsAtCompileTime
29 };
30
31 // even though we require Arg1, Arg2, and Arg3 to have the same scalar type
32 // (see CwiseTernaryOp constructor),
33 // we still want to handle the case when the result type is different.
34 typedef typename result_of<TernaryOp(
35 const typename Arg1::Scalar&, const typename Arg2::Scalar&,
36 const typename Arg3::Scalar&)>::type Scalar;
37
38 typedef typename internal::traits<Arg1>::StorageKind StorageKind;
39 typedef typename internal::traits<Arg1>::StorageIndex StorageIndex;
40
41 typedef typename Arg1::Nested Arg1Nested;
42 typedef typename Arg2::Nested Arg2Nested;
43 typedef typename Arg3::Nested Arg3Nested;
44 typedef typename remove_reference<Arg1Nested>::type _Arg1Nested;
45 typedef typename remove_reference<Arg2Nested>::type _Arg2Nested;
46 typedef typename remove_reference<Arg3Nested>::type _Arg3Nested;
47 enum { Flags = _Arg1Nested::Flags & RowMajorBit };
48};
49} // end namespace internal
50
51template <typename TernaryOp, typename Arg1, typename Arg2, typename Arg3,
52 typename StorageKind>
53class CwiseTernaryOpImpl;
54
55/** \class CwiseTernaryOp
56 * \ingroup Core_Module
57 *
58 * \brief Generic expression where a coefficient-wise ternary operator is
59 * applied to two expressions
60 *
61 * \tparam TernaryOp template functor implementing the operator
62 * \tparam Arg1Type the type of the first argument
63 * \tparam Arg2Type the type of the second argument
64 * \tparam Arg3Type the type of the third argument
65 *
66 * This class represents an expression where a coefficient-wise ternary
67 * operator is applied to three expressions.
68 * It is the return type of ternary operators, by which we mean only those
69 * ternary operators where
70 * all three arguments are Eigen expressions.
71 * For example, the return type of betainc(matrix1, matrix2, matrix3) is a
72 * CwiseTernaryOp.
73 *
74 * Most of the time, this is the only way that it is used, so you typically
75 * don't have to name
76 * CwiseTernaryOp types explicitly.
77 *
78 * \sa MatrixBase::ternaryExpr(const MatrixBase<Argument2> &, const
79 * MatrixBase<Argument3> &, const CustomTernaryOp &) const, class CwiseBinaryOp,
80 * class CwiseUnaryOp, class CwiseNullaryOp
81 */
82template <typename TernaryOp, typename Arg1Type, typename Arg2Type,
83 typename Arg3Type>
84class CwiseTernaryOp : public CwiseTernaryOpImpl<
85 TernaryOp, Arg1Type, Arg2Type, Arg3Type,
86 typename internal::traits<Arg1Type>::StorageKind>,
87 internal::no_assignment_operator
88{
89 public:
90 typedef typename internal::remove_all<Arg1Type>::type Arg1;
91 typedef typename internal::remove_all<Arg2Type>::type Arg2;
92 typedef typename internal::remove_all<Arg3Type>::type Arg3;
93
94 typedef typename CwiseTernaryOpImpl<
95 TernaryOp, Arg1Type, Arg2Type, Arg3Type,
96 typename internal::traits<Arg1Type>::StorageKind>::Base Base;
97 EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseTernaryOp)
98
99 typedef typename internal::ref_selector<Arg1Type>::type Arg1Nested;
100 typedef typename internal::ref_selector<Arg2Type>::type Arg2Nested;
101 typedef typename internal::ref_selector<Arg3Type>::type Arg3Nested;
102 typedef typename internal::remove_reference<Arg1Nested>::type _Arg1Nested;
103 typedef typename internal::remove_reference<Arg2Nested>::type _Arg2Nested;
104 typedef typename internal::remove_reference<Arg3Nested>::type _Arg3Nested;
105
106 EIGEN_DEVICE_FUNC
107 EIGEN_STRONG_INLINE CwiseTernaryOp(const Arg1& a1, const Arg2& a2,
108 const Arg3& a3,
109 const TernaryOp& func = TernaryOp())
110 : m_arg1(a1), m_arg2(a2), m_arg3(a3), m_functor(func) {
111 // require the sizes to match
112 EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Arg1, Arg2)
113 EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Arg1, Arg3)
114
115 // The index types should match
116 EIGEN_STATIC_ASSERT((internal::is_same<
117 typename internal::traits<Arg1Type>::StorageKind,
118 typename internal::traits<Arg2Type>::StorageKind>::value),
119 STORAGE_KIND_MUST_MATCH)
120 EIGEN_STATIC_ASSERT((internal::is_same<
121 typename internal::traits<Arg1Type>::StorageKind,
122 typename internal::traits<Arg3Type>::StorageKind>::value),
123 STORAGE_KIND_MUST_MATCH)
124
125 eigen_assert(a1.rows() == a2.rows() && a1.cols() == a2.cols() &&
126 a1.rows() == a3.rows() && a1.cols() == a3.cols());
127 }
128
129 EIGEN_DEVICE_FUNC
130 EIGEN_STRONG_INLINE Index rows() const {
131 // return the fixed size type if available to enable compile time
132 // optimizations
133 if (internal::traits<typename internal::remove_all<Arg1Nested>::type>::
134 RowsAtCompileTime == Dynamic &&
135 internal::traits<typename internal::remove_all<Arg2Nested>::type>::
136 RowsAtCompileTime == Dynamic)
137 return m_arg3.rows();
138 else if (internal::traits<typename internal::remove_all<Arg1Nested>::type>::
139 RowsAtCompileTime == Dynamic &&
140 internal::traits<typename internal::remove_all<Arg3Nested>::type>::
141 RowsAtCompileTime == Dynamic)
142 return m_arg2.rows();
143 else
144 return m_arg1.rows();
145 }
146 EIGEN_DEVICE_FUNC
147 EIGEN_STRONG_INLINE Index cols() const {
148 // return the fixed size type if available to enable compile time
149 // optimizations
150 if (internal::traits<typename internal::remove_all<Arg1Nested>::type>::
151 ColsAtCompileTime == Dynamic &&
152 internal::traits<typename internal::remove_all<Arg2Nested>::type>::
153 ColsAtCompileTime == Dynamic)
154 return m_arg3.cols();
155 else if (internal::traits<typename internal::remove_all<Arg1Nested>::type>::
156 ColsAtCompileTime == Dynamic &&
157 internal::traits<typename internal::remove_all<Arg3Nested>::type>::
158 ColsAtCompileTime == Dynamic)
159 return m_arg2.cols();
160 else
161 return m_arg1.cols();
162 }
163
164 /** \returns the first argument nested expression */
165 EIGEN_DEVICE_FUNC
166 const _Arg1Nested& arg1() const { return m_arg1; }
167 /** \returns the first argument nested expression */
168 EIGEN_DEVICE_FUNC
169 const _Arg2Nested& arg2() const { return m_arg2; }
170 /** \returns the third argument nested expression */
171 EIGEN_DEVICE_FUNC
172 const _Arg3Nested& arg3() const { return m_arg3; }
173 /** \returns the functor representing the ternary operation */
174 EIGEN_DEVICE_FUNC
175 const TernaryOp& functor() const { return m_functor; }
176
177 protected:
178 Arg1Nested m_arg1;
179 Arg2Nested m_arg2;
180 Arg3Nested m_arg3;
181 const TernaryOp m_functor;
182};
183
184// Generic API dispatcher
185template <typename TernaryOp, typename Arg1, typename Arg2, typename Arg3,
186 typename StorageKind>
187class CwiseTernaryOpImpl
188 : public internal::generic_xpr_base<
189 CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> >::type {
190 public:
191 typedef typename internal::generic_xpr_base<
192 CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> >::type Base;
193};
194
195} // end namespace Eigen
196
197#endif // EIGEN_CWISE_TERNARY_OP_H
198

source code of qtmultimedia/src/3rdparty/eigen/Eigen/src/Core/CwiseTernaryOp.h