1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library
2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra.
3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla
7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed
8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_BLASUTIL_H
11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_BLASUTIL_H
12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file contains many lightweight helper classes used to
14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// implement and control fast level 2 and level 3 BLAS-like routines.
15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen {
17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal {
19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// forward declarations
21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename LhsScalar, typename RhsScalar, typename Index, int mr, int nr, bool ConjugateLhs=false, bool ConjugateRhs=false>
22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct gebp_kernel;
23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar, typename Index, int nr, int StorageOrder, bool Conjugate = false, bool PanelMode=false>
25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct gemm_pack_rhs;
26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar, typename Index, int Pack1, int Pack2, int StorageOrder, bool Conjugate = false, bool PanelMode = false>
28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct gemm_pack_lhs;
29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<
31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typename Index,
32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typename LhsScalar, int LhsStorageOrder, bool ConjugateLhs,
33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs,
34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  int ResStorageOrder>
35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct general_matrix_matrix_product;
36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Index, typename LhsScalar, int LhsStorageOrder, bool ConjugateLhs, typename RhsScalar, bool ConjugateRhs, int Version=Specialized>
38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct general_matrix_vector_product;
39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<bool Conjugate> struct conj_if;
42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> struct conj_if<true> {
44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  template<typename T>
457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  inline T operator()(const T& x) { return numext::conj(x); }
46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  template<typename T>
47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  inline T pconj(const T& x) { return internal::pconj(x); }
48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> struct conj_if<false> {
51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  template<typename T>
52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  inline const T& operator()(const T& x) { return x; }
53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  template<typename T>
54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  inline const T& pconj(const T& x) { return x; }
55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar> struct conj_helper<Scalar,Scalar,false,false>
58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_STRONG_INLINE Scalar pmadd(const Scalar& x, const Scalar& y, const Scalar& c) const { return internal::pmadd(x,y,c); }
60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const { return internal::pmul(x,y); }
61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename RealScalar> struct conj_helper<std::complex<RealScalar>, std::complex<RealScalar>, false,true>
64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef std::complex<RealScalar> Scalar;
66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_STRONG_INLINE Scalar pmadd(const Scalar& x, const Scalar& y, const Scalar& c) const
67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  { return c + pmul(x,y); }
68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const
707faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  { return Scalar(numext::real(x)*numext::real(y) + numext::imag(x)*numext::imag(y), numext::imag(x)*numext::real(y) - numext::real(x)*numext::imag(y)); }
71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename RealScalar> struct conj_helper<std::complex<RealScalar>, std::complex<RealScalar>, true,false>
74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef std::complex<RealScalar> Scalar;
76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_STRONG_INLINE Scalar pmadd(const Scalar& x, const Scalar& y, const Scalar& c) const
77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  { return c + pmul(x,y); }
78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const
807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  { return Scalar(numext::real(x)*numext::real(y) + numext::imag(x)*numext::imag(y), numext::real(x)*numext::imag(y) - numext::imag(x)*numext::real(y)); }
81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename RealScalar> struct conj_helper<std::complex<RealScalar>, std::complex<RealScalar>, true,true>
84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef std::complex<RealScalar> Scalar;
86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_STRONG_INLINE Scalar pmadd(const Scalar& x, const Scalar& y, const Scalar& c) const
87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  { return c + pmul(x,y); }
88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const
907faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  { return Scalar(numext::real(x)*numext::real(y) - numext::imag(x)*numext::imag(y), - numext::real(x)*numext::imag(y) - numext::imag(x)*numext::real(y)); }
91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename RealScalar,bool Conj> struct conj_helper<std::complex<RealScalar>, RealScalar, Conj,false>
94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef std::complex<RealScalar> Scalar;
96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_STRONG_INLINE Scalar pmadd(const Scalar& x, const RealScalar& y, const Scalar& c) const
97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  { return padd(c, pmul(x,y)); }
98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const RealScalar& y) const
99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  { return conj_if<Conj>()(x)*y; }
100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename RealScalar,bool Conj> struct conj_helper<RealScalar, std::complex<RealScalar>, false,Conj>
103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef std::complex<RealScalar> Scalar;
105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_STRONG_INLINE Scalar pmadd(const RealScalar& x, const Scalar& y, const Scalar& c) const
106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  { return padd(c, pmul(x,y)); }
107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_STRONG_INLINE Scalar pmul(const RealScalar& x, const Scalar& y) const
108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  { return x*conj_if<Conj>()(y); }
109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename From,typename To> struct get_factor {
112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static EIGEN_STRONG_INLINE To run(const From& x) { return x; }
113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar> struct get_factor<Scalar,typename NumTraits<Scalar>::Real> {
1167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  static EIGEN_STRONG_INLINE typename NumTraits<Scalar>::Real run(const Scalar& x) { return numext::real(x); }
117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Lightweight helper class to access matrix coefficients.
120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Yes, this is somehow redundant with Map<>, but this version is much much lighter,
121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// and so I hope better compilation performance (time and code quality).
122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar, typename Index, int StorageOrder>
123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass blas_data_mapper
124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    blas_data_mapper(Scalar* data, Index stride) : m_data(data), m_stride(stride) {}
127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Scalar& operator()(Index i, Index j)
128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { return m_data[StorageOrder==RowMajor ? j + i*m_stride : i + j*m_stride]; }
129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  protected:
130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Scalar* EIGEN_RESTRICT m_data;
131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Index m_stride;
132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// lightweight helper class to access matrix coefficients (const version)
135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar, typename Index, int StorageOrder>
136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass const_blas_data_mapper
137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const_blas_data_mapper(const Scalar* data, Index stride) : m_data(data), m_stride(stride) {}
140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE const Scalar& operator()(Index i, Index j) const
141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { return m_data[StorageOrder==RowMajor ? j + i*m_stride : i + j*m_stride]; }
142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  protected:
143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const Scalar* EIGEN_RESTRICT m_data;
144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Index m_stride;
145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/* Helper class to analyze the factors of a Product expression.
149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * In particular it allows to pop out operator-, scalar multiples,
150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * and conjugate */
151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename XprType> struct blas_traits
152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename traits<XprType>::Scalar Scalar;
154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef const XprType& ExtractType;
155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef XprType _ExtractType;
156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    IsComplex = NumTraits<Scalar>::IsComplex,
158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    IsTransposed = false,
159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    NeedToConjugate = false,
160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasUsableDirectAccess = (    (int(XprType::Flags)&DirectAccessBit)
161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                              && (   bool(XprType::IsVectorAtCompileTime)
162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                                  || int(inner_stride_at_compile_time<XprType>::ret) == 1)
163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                             ) ?  1 : 0
164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename conditional<bool(HasUsableDirectAccess),
166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ExtractType,
167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typename _ExtractType::PlainObject
168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    >::type DirectLinearAccessType;
169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline ExtractType extract(const XprType& x) { return x; }
170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline const Scalar extractScalarFactor(const XprType&) { return Scalar(1); }
171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// pop conjugate
174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar, typename NestedXpr>
175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct blas_traits<CwiseUnaryOp<scalar_conjugate_op<Scalar>, NestedXpr> >
176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : blas_traits<NestedXpr>
177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef blas_traits<NestedXpr> Base;
179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef CwiseUnaryOp<scalar_conjugate_op<Scalar>, NestedXpr> XprType;
180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename Base::ExtractType ExtractType;
181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    IsComplex = NumTraits<Scalar>::IsComplex,
184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    NeedToConjugate = Base::NeedToConjugate ? 0 : IsComplex
185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); }
187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline Scalar extractScalarFactor(const XprType& x) { return conj(Base::extractScalarFactor(x.nestedExpression())); }
188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// pop scalar multiple
191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar, typename NestedXpr>
192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct blas_traits<CwiseUnaryOp<scalar_multiple_op<Scalar>, NestedXpr> >
193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : blas_traits<NestedXpr>
194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef blas_traits<NestedXpr> Base;
196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef CwiseUnaryOp<scalar_multiple_op<Scalar>, NestedXpr> XprType;
197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename Base::ExtractType ExtractType;
198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); }
199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline Scalar extractScalarFactor(const XprType& x)
200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  { return x.functor().m_other * Base::extractScalarFactor(x.nestedExpression()); }
201c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// pop opposite
204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar, typename NestedXpr>
205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct blas_traits<CwiseUnaryOp<scalar_opposite_op<Scalar>, NestedXpr> >
206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : blas_traits<NestedXpr>
207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef blas_traits<NestedXpr> Base;
209c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef CwiseUnaryOp<scalar_opposite_op<Scalar>, NestedXpr> XprType;
210c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename Base::ExtractType ExtractType;
211c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); }
212c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline Scalar extractScalarFactor(const XprType& x)
213c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  { return - Base::extractScalarFactor(x.nestedExpression()); }
214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// pop/push transpose
217c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename NestedXpr>
218c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct blas_traits<Transpose<NestedXpr> >
219c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : blas_traits<NestedXpr>
220c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
221c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename NestedXpr::Scalar Scalar;
222c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef blas_traits<NestedXpr> Base;
223c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Transpose<NestedXpr> XprType;
224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Transpose<const typename Base::_ExtractType>  ExtractType; // const to get rid of a compile error; anyway blas traits are only used on the RHS
225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Transpose<const typename Base::_ExtractType> _ExtractType;
226c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename conditional<bool(Base::HasUsableDirectAccess),
227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ExtractType,
228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typename ExtractType::PlainObject
229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    >::type DirectLinearAccessType;
230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    IsTransposed = Base::IsTransposed ? 0 : 1
232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); }
234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline Scalar extractScalarFactor(const XprType& x) { return Base::extractScalarFactor(x.nestedExpression()); }
235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
237c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T>
238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct blas_traits<const T>
239c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath     : blas_traits<T>
240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{};
241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T, bool HasUsableDirectAccess=blas_traits<T>::HasUsableDirectAccess>
243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct extract_data_selector {
244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static const typename T::Scalar* run(const T& m)
245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
246c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return blas_traits<T>::extract(m).data();
247c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
248c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
249c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
250c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T>
251c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct extract_data_selector<T,false> {
252c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static typename T::Scalar* run(const T&) { return 0; }
253c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
254c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
255c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T> const typename T::Scalar* extract_data(const T& m)
256c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
257c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return extract_data_selector<T>::run(m);
258c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
259c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
260c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal
261c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
262c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen
263c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
264c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_BLASUTIL_H
265