10#ifndef EIGEN_PRODUCT_H
11#define EIGEN_PRODUCT_H
14#include "./InternalHeaderCheck.h"
18template <
typename Lhs,
typename Rhs,
int Option,
typename StorageKind>
23template <
typename Lhs,
typename Rhs,
int Option>
24struct traits<Product<Lhs, Rhs, Option>> {
25 typedef remove_all_t<Lhs> LhsCleaned;
26 typedef remove_all_t<Rhs> RhsCleaned;
27 typedef traits<LhsCleaned> LhsTraits;
28 typedef traits<RhsCleaned> RhsTraits;
30 typedef MatrixXpr XprKind;
32 typedef typename ScalarBinaryOpTraits<typename traits<LhsCleaned>::Scalar,
33 typename traits<RhsCleaned>::Scalar>::ReturnType Scalar;
34 typedef typename product_promote_storage_type<
typename LhsTraits::StorageKind,
typename RhsTraits::StorageKind,
35 internal::product_type<Lhs, Rhs>::ret>::ret StorageKind;
36 typedef typename promote_index_type<typename LhsTraits::StorageIndex, typename RhsTraits::StorageIndex>::type
40 RowsAtCompileTime = LhsTraits::RowsAtCompileTime,
41 ColsAtCompileTime = RhsTraits::ColsAtCompileTime,
42 MaxRowsAtCompileTime = LhsTraits::MaxRowsAtCompileTime,
43 MaxColsAtCompileTime = RhsTraits::MaxColsAtCompileTime,
46 InnerSize = min_size_prefer_fixed(LhsTraits::ColsAtCompileTime, RhsTraits::RowsAtCompileTime),
49 Flags = (MaxRowsAtCompileTime == 1 && MaxColsAtCompileTime != 1) ? RowMajorBit
50 : (MaxColsAtCompileTime == 1 && MaxRowsAtCompileTime != 1) ? 0
58struct TransposeProductEnum {
64 MatrixMatrix = (Matrix << 8) | Matrix,
65 MatrixPermutation = (Matrix << 8) | Permutation,
66 PermutationMatrix = (Permutation << 8) | Matrix
69template <
typename Xpr>
71 static constexpr int Kind = is_matrix_base_xpr<Xpr>::value ? TransposeProductEnum::Matrix
72 : is_permutation_base_xpr<Xpr>::value ? TransposeProductEnum::Permutation
73 : TransposeProductEnum::Default;
76template <
typename Lhs,
typename Rhs>
77struct TransposeProductKind {
78 static constexpr int Kind = (TransposeKind<Lhs>::Kind << 8) | TransposeKind<Rhs>::Kind;
81template <typename Lhs, typename Rhs, int Option, int Kind = TransposeProductKind<Lhs, Rhs>::Kind>
82struct product_transpose_helper {
84 using Derived = Product<Lhs, Rhs, Option>;
85 using Scalar =
typename Derived::Scalar;
86 using TransposeType = Transpose<const Derived>;
87 using ConjugateTransposeType = CwiseUnaryOp<scalar_conjugate_op<Scalar>, TransposeType>;
88 using AdjointType = std::conditional_t<NumTraits<Scalar>::IsComplex, ConjugateTransposeType, TransposeType>;
91 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TransposeType run_transpose(
const Derived& derived) {
92 return TransposeType(derived);
95 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE AdjointType run_adjoint(
const Derived& derived) {
96 return AdjointType(TransposeType(derived));
100template <
typename Lhs,
typename Rhs,
int Option>
101struct product_transpose_helper<Lhs, Rhs, Option, TransposeProductEnum::MatrixMatrix> {
103 using Derived = Product<Lhs, Rhs, Option>;
105 using LhsScalar =
typename traits<Lhs>::Scalar;
106 using LhsTransposeType =
typename DenseBase<Lhs>::ConstTransposeReturnType;
107 using LhsConjugateTransposeType = CwiseUnaryOp<scalar_conjugate_op<LhsScalar>, LhsTransposeType>;
108 using LhsAdjointType =
109 std::conditional_t<NumTraits<LhsScalar>::IsComplex, LhsConjugateTransposeType, LhsTransposeType>;
111 using RhsScalar =
typename traits<Rhs>::Scalar;
112 using RhsTransposeType =
typename DenseBase<Rhs>::ConstTransposeReturnType;
113 using RhsConjugateTransposeType = CwiseUnaryOp<scalar_conjugate_op<RhsScalar>, RhsTransposeType>;
114 using RhsAdjointType =
115 std::conditional_t<NumTraits<RhsScalar>::IsComplex, RhsConjugateTransposeType, RhsTransposeType>;
117 using TransposeType = Product<RhsTransposeType, LhsTransposeType, Option>;
118 using AdjointType = Product<RhsAdjointType, LhsAdjointType, Option>;
121 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TransposeType run_transpose(
const Derived& derived) {
122 return TransposeType(RhsTransposeType(derived.rhs()), LhsTransposeType(derived.lhs()));
125 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE AdjointType run_adjoint(
const Derived& derived) {
126 return AdjointType(RhsAdjointType(RhsTransposeType(derived.rhs())),
127 LhsAdjointType(LhsTransposeType(derived.lhs())));
130template <
typename Lhs,
typename Rhs,
int Option>
131struct product_transpose_helper<Lhs, Rhs, Option, TransposeProductEnum::PermutationMatrix> {
133 using Derived = Product<Lhs, Rhs, Option>;
135 using LhsInverseType =
typename PermutationBase<Lhs>::InverseReturnType;
137 using RhsScalar =
typename traits<Rhs>::Scalar;
138 using RhsTransposeType =
typename DenseBase<Rhs>::ConstTransposeReturnType;
139 using RhsConjugateTransposeType = CwiseUnaryOp<scalar_conjugate_op<RhsScalar>, RhsTransposeType>;
140 using RhsAdjointType =
141 std::conditional_t<NumTraits<RhsScalar>::IsComplex, RhsConjugateTransposeType, RhsTransposeType>;
143 using TransposeType = Product<RhsTransposeType, LhsInverseType, Option>;
144 using AdjointType = Product<RhsAdjointType, LhsInverseType, Option>;
147 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TransposeType run_transpose(
const Derived& derived) {
148 return TransposeType(RhsTransposeType(derived.rhs()), LhsInverseType(derived.lhs()));
151 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE AdjointType run_adjoint(
const Derived& derived) {
152 return AdjointType(RhsAdjointType(RhsTransposeType(derived.rhs())), LhsInverseType(derived.lhs()));
155template <
typename Lhs,
typename Rhs,
int Option>
156struct product_transpose_helper<Lhs, Rhs, Option, TransposeProductEnum::MatrixPermutation> {
158 using Derived = Product<Lhs, Rhs, Option>;
160 using LhsScalar =
typename traits<Lhs>::Scalar;
161 using LhsTransposeType =
typename DenseBase<Lhs>::ConstTransposeReturnType;
162 using LhsConjugateTransposeType = CwiseUnaryOp<scalar_conjugate_op<LhsScalar>, LhsTransposeType>;
163 using LhsAdjointType =
164 std::conditional_t<NumTraits<LhsScalar>::IsComplex, LhsConjugateTransposeType, LhsTransposeType>;
166 using RhsInverseType =
typename PermutationBase<Rhs>::InverseReturnType;
168 using TransposeType = Product<RhsInverseType, LhsTransposeType, Option>;
169 using AdjointType = Product<RhsInverseType, LhsAdjointType, Option>;
172 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TransposeType run_transpose(
const Derived& derived) {
173 return TransposeType(RhsInverseType(derived.rhs()), LhsTransposeType(derived.lhs()));
176 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE AdjointType run_adjoint(
const Derived& derived) {
177 return AdjointType(RhsInverseType(derived.rhs()), LhsAdjointType(LhsTransposeType(derived.lhs())));
197template <
typename Lhs_,
typename Rhs_,
int Option>
199 :
public ProductImpl<Lhs_, Rhs_, Option,
200 typename internal::product_promote_storage_type<
201 typename internal::traits<Lhs_>::StorageKind, typename internal::traits<Rhs_>::StorageKind,
202 internal::product_type<Lhs_, Rhs_>::ret>::ret> {
208 typename ProductImpl<Lhs, Rhs, Option,
209 typename internal::product_promote_storage_type<
210 typename internal::traits<Lhs>::StorageKind,
typename internal::traits<Rhs>::StorageKind,
211 internal::product_type<Lhs, Rhs>::ret>::ret>::Base Base;
212 EIGEN_GENERIC_PUBLIC_INTERFACE(
Product)
214 typedef typename internal::ref_selector<Lhs>::type LhsNested;
215 typedef typename internal::ref_selector<Rhs>::type RhsNested;
216 typedef internal::remove_all_t<LhsNested> LhsNestedCleaned;
217 typedef internal::remove_all_t<RhsNested> RhsNestedCleaned;
220 using AdjointReturnType =
typename internal::product_transpose_helper<Lhs, Rhs, Option>::AdjointType;
222 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Product(
const Lhs& lhs,
const Rhs& rhs) : m_lhs(lhs), m_rhs(rhs) {
223 eigen_assert(lhs.cols() == rhs.rows() &&
"invalid matrix product" &&
224 "if you wanted a coeff-wise or a dot product use the respective explicit functions");
227 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Index rows()
const EIGEN_NOEXCEPT {
return m_lhs.rows(); }
228 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Index cols()
const EIGEN_NOEXCEPT {
return m_rhs.cols(); }
230 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const LhsNestedCleaned& lhs()
const {
return m_lhs; }
231 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const RhsNestedCleaned& rhs()
const {
return m_rhs; }
233 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TransposeReturnType transpose()
const {
234 return internal::product_transpose_helper<Lhs, Rhs, Option>::run_transpose(*
this);
236 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE AdjointReturnType adjoint()
const {
237 return internal::product_transpose_helper<Lhs, Rhs, Option>::run_adjoint(*
this);
247template <typename Lhs, typename Rhs, int Option, int ProductTag = internal::product_type<Lhs, Rhs>::ret>
248class dense_product_base :
public internal::dense_xpr_base<Product<Lhs, Rhs, Option>>::type {};
251template <
typename Lhs,
typename Rhs,
int Option>
252class dense_product_base<Lhs, Rhs, Option, InnerProduct>
253 :
public internal::dense_xpr_base<Product<Lhs, Rhs, Option>>::type {
254 typedef Product<Lhs, Rhs, Option> ProductXpr;
255 typedef typename internal::dense_xpr_base<ProductXpr>::type Base;
259 typedef typename Base::Scalar Scalar;
261 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
operator const Scalar()
const {
262 return internal::evaluator<ProductXpr>(derived()).coeff(0, 0);
269template <
typename Lhs,
typename Rhs,
int Option,
typename StorageKind>
270class ProductImpl :
public internal::generic_xpr_base<Product<Lhs, Rhs, Option>, MatrixXpr, StorageKind>::type {
272 typedef typename internal::generic_xpr_base<Product<Lhs, Rhs, Option>, MatrixXpr, StorageKind>::type Base;
275template <
typename Lhs,
typename Rhs,
int Option>
276class ProductImpl<Lhs, Rhs, Option, Dense> :
public internal::dense_product_base<Lhs, Rhs, Option> {
277 typedef Product<Lhs, Rhs, Option> Derived;
280 typedef typename internal::dense_product_base<Lhs, Rhs, Option> Base;
281 EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
284 IsOneByOne = (RowsAtCompileTime == 1 || RowsAtCompileTime ==
Dynamic) &&
285 (ColsAtCompileTime == 1 || ColsAtCompileTime == Dynamic),
286 EnableCoeff = IsOneByOne || Option == LazyProduct
290 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar coeff(Index row, Index col)
const {
291 EIGEN_STATIC_ASSERT(EnableCoeff, THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS);
292 eigen_assert((Option == LazyProduct) || (this->rows() == 1 && this->cols() == 1));
294 return internal::evaluator<Derived>(derived()).coeff(row, col);
297 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar coeff(Index i)
const {
298 EIGEN_STATIC_ASSERT(EnableCoeff, THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS);
299 eigen_assert((Option == LazyProduct) || (this->rows() == 1 && this->cols() == 1));
301 return internal::evaluator<Derived>(derived()).coeff(i);
Expression of the product of two arbitrary matrices or vectors.
Definition Product.h:202
Expression of the transpose of a matrix.
Definition Transpose.h:56
const unsigned int NoPreferredStorageOrderBit
Definition Constants.h:182
const unsigned int RowMajorBit
Definition Constants.h:70
Namespace containing all symbols from the Eigen library.
Definition Core:137
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:83
const int Dynamic
Definition Constants.h:25