Medial Code Documentation
Loading...
Searching...
No Matches
Transpose.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
5// Copyright (C) 2009-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
6//
7// This Source Code Form is subject to the terms of the Mozilla
8// Public License v. 2.0. If a copy of the MPL was not distributed
9// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10
11#ifndef EIGEN_TRANSPOSE_H
12#define EIGEN_TRANSPOSE_H
13
14namespace Eigen {
15
30namespace internal {
31template<typename MatrixType>
32struct traits<Transpose<MatrixType> > : public traits<MatrixType>
33{
35 typedef typename remove_reference<MatrixTypeNested>::type MatrixTypeNestedPlain;
36 enum {
37 RowsAtCompileTime = MatrixType::ColsAtCompileTime,
38 ColsAtCompileTime = MatrixType::RowsAtCompileTime,
39 MaxRowsAtCompileTime = MatrixType::MaxColsAtCompileTime,
40 MaxColsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
41 FlagsLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
42 Flags0 = traits<MatrixTypeNestedPlain>::Flags & ~(LvalueBit | NestByRefBit),
43 Flags1 = Flags0 | FlagsLvalueBit,
44 Flags = Flags1 ^ RowMajorBit,
45 InnerStrideAtCompileTime = inner_stride_at_compile_time<MatrixType>::ret,
46 OuterStrideAtCompileTime = outer_stride_at_compile_time<MatrixType>::ret
47 };
48};
49}
50
51template<typename MatrixType, typename StorageKind> class TransposeImpl;
52
53template<typename MatrixType> class Transpose
54 : public TransposeImpl<MatrixType,typename internal::traits<MatrixType>::StorageKind>
55{
56 public:
57
59 EIGEN_GENERIC_PUBLIC_INTERFACE(Transpose)
61
63 explicit inline Transpose(MatrixType& matrix) : m_matrix(matrix) {}
64
65 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Transpose)
66
67 EIGEN_DEVICE_FUNC inline Index rows() const { return m_matrix.cols(); }
68 EIGEN_DEVICE_FUNC inline Index cols() const { return m_matrix.rows(); }
69
73 nestedExpression() const { return m_matrix; }
74
78 nestedExpression() { return m_matrix.const_cast_derived(); }
79
80 protected:
81 typename MatrixType::Nested m_matrix;
82};
83
84namespace internal {
85
86template<typename MatrixType, bool HasDirectAccess = has_direct_access<MatrixType>::ret>
88{
89 typedef typename dense_xpr_base<Transpose<MatrixType> >::type type;
90};
91
92template<typename MatrixType>
93struct TransposeImpl_base<MatrixType, false>
94{
95 typedef typename dense_xpr_base<Transpose<MatrixType> >::type type;
96};
97
98} // end namespace internal
99
100// Generic API dispatcher
101template<typename XprType, typename StorageKind>
103 : public internal::generic_xpr_base<Transpose<XprType> >::type
104{
105public:
106 typedef typename internal::generic_xpr_base<Transpose<XprType> >::type Base;
107};
108
109template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
110 : public internal::TransposeImpl_base<MatrixType>::type
111{
112 public:
113
114 typedef typename internal::TransposeImpl_base<MatrixType>::type Base;
115 using Base::coeffRef;
116 EIGEN_DENSE_PUBLIC_INTERFACE(Transpose<MatrixType>)
117 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TransposeImpl)
118
119 EIGEN_DEVICE_FUNC inline Index innerStride() const { return derived().nestedExpression().innerStride(); }
120 EIGEN_DEVICE_FUNC inline Index outerStride() const { return derived().nestedExpression().outerStride(); }
121
122 typedef typename internal::conditional<
124 Scalar,
125 const Scalar
127
128 EIGEN_DEVICE_FUNC inline ScalarWithConstIfNotLvalue* data() { return derived().nestedExpression().data(); }
129 EIGEN_DEVICE_FUNC inline const Scalar* data() const { return derived().nestedExpression().data(); }
130
131 // FIXME: shall we keep the const version of coeffRef?
133 inline const Scalar& coeffRef(Index rowId, Index colId) const
134 {
135 return derived().nestedExpression().coeffRef(colId, rowId);
136 }
137
139 inline const Scalar& coeffRef(Index index) const
140 {
141 return derived().nestedExpression().coeffRef(index);
142 }
143};
144
164template<typename Derived>
167{
168 return TransposeReturnType(derived());
169}
170
176template<typename Derived>
179{
180 return ConstTransposeReturnType(derived());
181}
182
202template<typename Derived>
203inline const typename MatrixBase<Derived>::AdjointReturnType
205{
206 return AdjointReturnType(this->transpose());
207}
208
209/***************************************************************************
210* "in place" transpose implementation
211***************************************************************************/
212
213namespace internal {
214
215template<typename MatrixType,
216 bool IsSquare = (MatrixType::RowsAtCompileTime == MatrixType::ColsAtCompileTime) && MatrixType::RowsAtCompileTime!=Dynamic,
217 bool MatchPacketSize =
218 (int(MatrixType::RowsAtCompileTime) == int(internal::packet_traits<typename MatrixType::Scalar>::size))
221
222template<typename MatrixType>
223struct inplace_transpose_selector<MatrixType,true,false> { // square matrix
224 static void run(MatrixType& m) {
225 m.matrix().template triangularView<StrictlyUpper>().swap(m.matrix().transpose());
226 }
227};
228
229// TODO: vectorized path is currently limited to LargestPacketSize x LargestPacketSize cases only.
230template<typename MatrixType>
231struct inplace_transpose_selector<MatrixType,true,true> { // PacketSize x PacketSize
232 static void run(MatrixType& m) {
233 typedef typename MatrixType::Scalar Scalar;
234 typedef typename internal::packet_traits<typename MatrixType::Scalar>::type Packet;
235 const Index PacketSize = internal::packet_traits<Scalar>::size;
236 const Index Alignment = internal::evaluator<MatrixType>::Alignment;
238 for (Index i=0; i<PacketSize; ++i)
239 A.packet[i] = m.template packetByOuterInner<Alignment>(i,0);
240 internal::ptranspose(A);
241 for (Index i=0; i<PacketSize; ++i)
242 m.template writePacket<Alignment>(m.rowIndexByOuterInner(i,0), m.colIndexByOuterInner(i,0), A.packet[i]);
243 }
244};
245
246template<typename MatrixType,bool MatchPacketSize>
247struct inplace_transpose_selector<MatrixType,false,MatchPacketSize> { // non square matrix
248 static void run(MatrixType& m) {
249 if (m.rows()==m.cols())
250 m.matrix().template triangularView<StrictlyUpper>().swap(m.matrix().transpose());
251 else
252 m = m.transpose().eval();
253 }
254};
255
256} // end namespace internal
257
277template<typename Derived>
279{
280 eigen_assert((rows() == cols() || (RowsAtCompileTime == Dynamic && ColsAtCompileTime == Dynamic))
281 && "transposeInPlace() called on a non-square non-resizable matrix");
283}
284
285/***************************************************************************
286* "in place" adjoint implementation
287***************************************************************************/
288
308template<typename Derived>
310{
311 derived() = adjoint().eval();
312}
313
314#ifndef EIGEN_NO_DEBUG
315
316// The following is to detect aliasing problems in most common cases.
317
318namespace internal {
319
320template<bool DestIsTransposed, typename OtherDerived>
326template<bool DestIsTransposed, typename BinOp, typename DerivedA, typename DerivedB>
329 enum { ret = bool(blas_traits<DerivedA>::IsTransposed) != DestIsTransposed
330 || bool(blas_traits<DerivedB>::IsTransposed) != DestIsTransposed
331 };
332};
333
334template<typename Scalar, bool DestIsTransposed, typename OtherDerived>
336{
337 static bool run(const Scalar* dest, const OtherDerived& src)
338 {
339 return (bool(blas_traits<OtherDerived>::IsTransposed) != DestIsTransposed) && (dest!=0 && dest==(const Scalar*)extract_data(src));
340 }
341};
342
343template<typename Scalar, bool DestIsTransposed, typename BinOp, typename DerivedA, typename DerivedB>
345{
346 static bool run(const Scalar* dest, const CwiseBinaryOp<BinOp,DerivedA,DerivedB>& src)
347 {
348 return ((blas_traits<DerivedA>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(const Scalar*)extract_data(src.lhs())))
349 || ((blas_traits<DerivedB>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(const Scalar*)extract_data(src.rhs())));
350 }
351};
352
353// the following selector, checkTransposeAliasing_impl, based on MightHaveTransposeAliasing,
354// is because when the condition controlling the assert is known at compile time, ICC emits a warning.
355// This is actually a good warning: in expressions that don't have any transposing, the condition is
356// known at compile time to be false, and using that, we can avoid generating the code of the assert again
357// and again for all these expressions that don't need it.
358
359template<typename Derived, typename OtherDerived,
363 >
365{
366 static void run(const Derived& dst, const OtherDerived& other)
367 {
369 <typename Derived::Scalar,blas_traits<Derived>::IsTransposed,OtherDerived>
370 ::run(extract_data(dst), other))
371 && "aliasing detected during transposition, use transposeInPlace() "
372 "or evaluate the rhs into a temporary using .eval()");
373
374 }
375};
376
377template<typename Derived, typename OtherDerived>
379{
380 static void run(const Derived&, const OtherDerived&)
381 {
382 }
383};
384
385template<typename Dst, typename Src>
386void check_for_aliasing(const Dst &dst, const Src &src)
387{
389}
390
391} // end namespace internal
392
393#endif // EIGEN_NO_DEBUG
394
395} // end namespace Eigen
396
397#endif // EIGEN_TRANSPOSE_H
Generic expression where a coefficient-wise binary operator is applied to two expressions.
Definition CwiseBinaryOp.h:85
Base class for all dense matrices, vectors, and arrays.
Definition DenseBase.h:49
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:50
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EvalReturnType eval() const
Definition DenseBase.h:405
Pseudo expression representing a solving operation.
Definition Solve.h:63
Definition Transpose.h:104
Expression of the transpose of a matrix.
Definition Transpose.h:55
EIGEN_DEVICE_FUNC internal::remove_all< typenameMatrixType::Nested >::type & nestedExpression()
Definition Transpose.h:78
EIGEN_DEVICE_FUNC const internal::remove_all< typenameMatrixType::Nested >::type & nestedExpression() const
Definition Transpose.h:73
const unsigned int PacketAccessBit
Short version: means the expression might be vectorized.
Definition Constants.h:88
const unsigned int LvalueBit
Means the expression has a coeffRef() method, i.e.
Definition Constants.h:138
const unsigned int RowMajorBit
for a matrix, this means that the storage order is row-major.
Definition Constants.h:61
The type used to identify a dense storage.
Definition Constants.h:490
Definition Transpose.h:88
Definition BlasUtil.h:257
Definition Meta.h:34
Definition CoreEvaluators.h:82
Definition XprHelper.h:445
Definition DenseCoeffsBase.h:631
Definition XprHelper.h:628
Definition DenseCoeffsBase.h:643
Definition GenericPacketMath.h:90
Definition ForwardDeclarations.h:17
Definition Meta.h:30