25 #ifndef EIGEN_BLASUTIL_H
26 #define EIGEN_BLASUTIL_H
36 template<
typename LhsScalar,
typename RhsScalar,
typename Index,
int mr,
int nr,
bool ConjugateLhs=false,
bool ConjugateRhs=false>
39 template<
typename Scalar,
typename Index,
int nr,
int StorageOrder,
bool Conjugate = false,
bool PanelMode=false>
42 template<
typename Scalar,
typename Index,
int Pack1,
int Pack2,
int StorageOrder,
bool Conjugate = false,
bool PanelMode = false>
47 typename LhsScalar,
int LhsStorageOrder,
bool ConjugateLhs,
48 typename RhsScalar,
int RhsStorageOrder,
bool ConjugateRhs,
50 struct general_matrix_matrix_product;
52 template<
typename Index,
typename LhsScalar,
int LhsStorageOrder,
bool ConjugateLhs,
typename RhsScalar,
bool ConjugateRhs,
int Version=Specialized>
56 template<
bool Conjugate>
struct conj_if;
58 template<>
struct conj_if<true> {
60 inline T operator()(
const T& x) {
return conj(x); }
65 template<>
struct conj_if<false> {
67 inline const T& operator()(
const T& x) {
return x; }
69 inline const T&
pconj(
const T& x) {
return x; }
72 template<
typename Scalar>
struct conj_helper<Scalar,Scalar,false,false>
78 template<
typename RealScalar>
struct conj_helper<std::complex<RealScalar>, std::complex<RealScalar>, false,true>
80 typedef std::complex<RealScalar> Scalar;
82 {
return c +
pmul(x,y); }
88 template<
typename RealScalar>
struct conj_helper<std::complex<RealScalar>, std::complex<RealScalar>, true,false>
90 typedef std::complex<RealScalar> Scalar;
92 {
return c +
pmul(x,y); }
98 template<
typename RealScalar>
struct conj_helper<std::complex<RealScalar>, std::complex<RealScalar>, true,true>
100 typedef std::complex<RealScalar> Scalar;
102 {
return c +
pmul(x,y); }
108 template<
typename RealScalar,
bool Conj>
struct conj_helper<std::complex<RealScalar>, RealScalar, Conj,false>
110 typedef std::complex<RealScalar> Scalar;
114 {
return conj_if<Conj>()(x)*
y; }
117 template<
typename RealScalar,
bool Conj>
struct conj_helper<RealScalar, std::complex<RealScalar>, false,Conj>
119 typedef std::complex<RealScalar> Scalar;
123 {
return x*conj_if<Conj>()(y); }
126 template<
typename From,
typename To>
struct get_factor {
130 template<
typename Scalar>
struct get_factor<Scalar,typename NumTraits<Scalar>::Real> {
137 template<
typename Scalar,
typename Index,
int StorageOrder>
138 class blas_data_mapper
141 blas_data_mapper(Scalar* data, Index stride) : m_data(data), m_stride(stride) {}
143 {
return m_data[StorageOrder==
RowMajor ? j + i*m_stride : i + j*m_stride]; }
150 template<
typename Scalar,
typename Index,
int StorageOrder>
151 class const_blas_data_mapper
154 const_blas_data_mapper(
const Scalar* data, Index stride) : m_data(data), m_stride(stride) {}
156 {
return m_data[StorageOrder==
RowMajor ? j + i*m_stride : i + j*m_stride]; }
166 template<
typename XprType>
struct blas_traits
169 typedef const XprType& ExtractType;
170 typedef XprType _ExtractType;
173 IsTransposed =
false,
174 NeedToConjugate =
false,
176 && (
bool(XprType::IsVectorAtCompileTime)
177 ||
int(inner_stride_at_compile_time<XprType>::ret) == 1)
180 typedef typename conditional<
bool(HasUsableDirectAccess),
182 typename _ExtractType::PlainObject
183 >::type DirectLinearAccessType;
184 static inline ExtractType extract(
const XprType& x) {
return x; }
185 static inline const Scalar extractScalarFactor(
const XprType&) {
return Scalar(1); }
189 template<
typename Scalar,
typename NestedXpr>
190 struct blas_traits<CwiseUnaryOp<scalar_conjugate_op<Scalar>, NestedXpr> >
191 : blas_traits<NestedXpr>
193 typedef blas_traits<NestedXpr> Base;
194 typedef CwiseUnaryOp<scalar_conjugate_op<Scalar>, NestedXpr> XprType;
195 typedef typename Base::ExtractType ExtractType;
199 NeedToConjugate = Base::NeedToConjugate ? 0 :
IsComplex
201 static inline ExtractType extract(
const XprType& x) {
return Base::extract(x.nestedExpression()); }
202 static inline Scalar extractScalarFactor(
const XprType& x) {
return conj(Base::extractScalarFactor(x.nestedExpression())); }
206 template<
typename Scalar,
typename NestedXpr>
207 struct blas_traits<CwiseUnaryOp<scalar_multiple_op<Scalar>, NestedXpr> >
208 : blas_traits<NestedXpr>
210 typedef blas_traits<NestedXpr> Base;
211 typedef CwiseUnaryOp<scalar_multiple_op<Scalar>, NestedXpr> XprType;
212 typedef typename Base::ExtractType ExtractType;
213 static inline ExtractType extract(
const XprType& x) {
return Base::extract(x.nestedExpression()); }
214 static inline Scalar extractScalarFactor(
const XprType& x)
215 {
return x.functor().m_other * Base::extractScalarFactor(x.nestedExpression()); }
219 template<
typename Scalar,
typename NestedXpr>
220 struct blas_traits<CwiseUnaryOp<scalar_opposite_op<Scalar>, NestedXpr> >
221 : blas_traits<NestedXpr>
223 typedef blas_traits<NestedXpr> Base;
224 typedef CwiseUnaryOp<scalar_opposite_op<Scalar>, NestedXpr> XprType;
225 typedef typename Base::ExtractType ExtractType;
226 static inline ExtractType extract(
const XprType& x) {
return Base::extract(x.nestedExpression()); }
227 static inline Scalar extractScalarFactor(
const XprType& x)
228 {
return - Base::extractScalarFactor(x.nestedExpression()); }
232 template<
typename NestedXpr>
233 struct blas_traits<Transpose<NestedXpr> >
234 : blas_traits<NestedXpr>
236 typedef typename NestedXpr::Scalar Scalar;
237 typedef blas_traits<NestedXpr> Base;
238 typedef Transpose<NestedXpr> XprType;
239 typedef Transpose<const typename Base::_ExtractType> ExtractType;
240 typedef Transpose<const typename Base::_ExtractType> _ExtractType;
241 typedef typename conditional<
bool(Base::HasUsableDirectAccess),
243 typename ExtractType::PlainObject
244 >::type DirectLinearAccessType;
246 IsTransposed = Base::IsTransposed ? 0 : 1
248 static inline ExtractType extract(
const XprType& x) {
return Base::extract(x.nestedExpression()); }
249 static inline Scalar extractScalarFactor(
const XprType& x) {
return Base::extractScalarFactor(x.nestedExpression()); }
253 struct blas_traits<const T>
257 template<typename T, bool HasUsableDirectAccess=blas_traits<T>::HasUsableDirectAccess>
258 struct extract_data_selector {
259 static const typename T::Scalar* run(
const T& m)
261 return blas_traits<T>::extract(m).data();
266 struct extract_data_selector<T,false> {
267 static typename T::Scalar* run(
const T&) {
return 0; }
270 template<
typename T>
const typename T::Scalar*
extract_data(
const T& m)
272 return extract_data_selector<T>::run(m);
279 #endif // EIGEN_BLASUTIL_H