1#ifndef __DUNE_ACFEM_TENSORS_OPERATIONS_TRANSPOSETRAITS_HH__
2#define __DUNE_ACFEM_TENSORS_OPERATIONS_TRANSPOSETRAITS_HH__
4#include "../../mpl/compare.hh"
5#include "../../expressions/storage.hh"
6#include "../expressionoperations.hh"
7#include "../modules.hh"
37 template<
class Perm,
class T,
class SFINAE =
void>
42 template<
class Perm,
class T,
class SFINAE>
47 template<
class Perm,
class T,
class SFINAE>
48 struct IsSubordinateTransposition<Perm, T&&, SFINAE>
49 : IsSubordinateTransposition<Perm, std::decay_t<T>, SFINAE>
52 template<
class Perm,
class T>
53 struct IsSubordinateTransposition<
55 std::enable_if_t<IsDecay<T>::value && Perm::size() != TensorTraits<T>::rank> >
56 : IsSubordinateTransposition<ResizedPermutation<Perm, TensorTraits<T>::rank>, T>
62 template<
class Perm,
class T>
65 std::enable_if_t<(IsDecay<T>::value
66 && IsUnaryExpression<T>::value
67 && IsComponentWiseExpression<T>::value
68 && isPermutation(Perm{})
69 && Perm::size() == TensorTraits<T>::rank
75 template<
class Perm,
class T>
78 std::enable_if_t<(IsDecay<T>::value
79 && isPermutation(Perm{})
81 && Perm::size() == TensorTraits<T>::rank
82 && IsEinsumExpression<T>::value
84 :
BoolConstant<(isPermutation(SequenceSlice<Perm, typename T::LeftArgs>{})
86 isPermutation(SequenceCat<typename T::LeftArgs, SequenceSlice<Perm, typename T::RightArgs> >{}))>
90 template<
class Perm,
class T>
93 std::enable_if_t<(IsDecay<T>::value
94 && isPermutation(Perm{})
95 && Perm::size() == TensorTraits<T>::rank
96 && IsTensorProductExpression<T>::value
99 isPermutation(SequenceSlice<Perm, typename T::FrontArgs>{})
100 && isPermutation(OffsetSequence<-(int)T::frontRank_, SequenceSlice<Perm, typename T::LeftArgs> >{})
101 && isPermutation(OffsetSequence<-(int)(T::frontRank_+T::leftRank_), SequenceSlice<Perm, typename T::RightArgs> >{}))>
107 template<std::
size_t N,
class Perm,
class T,
class SFINAE =
void>
110 template<std::
size_t N,
class Perm,
class T>
114 template<std::
size_t N,
class PermArg,
class T>
117 std::enable_if_t<(IsSubordinateTransposition<PermArg, T>::value
118 && IsEinsumExpression<T>::value
119 && (N < Arity<T>::value)
123 using Traits = EinsumTraits<T>;
124 using LeftIndexPositions =
typename Traits::LeftIndexPositions;
125 using RightIndexPositions =
typename Traits::RightIndexPositions;
126 static constexpr std::ptrdiff_t leftRank_ = TensorTraits<Operand<0, T> >::rank;
127 static constexpr std::ptrdiff_t leftDefectRank_ = leftRank_ - Traits::defectRank_;
128 static constexpr std::ptrdiff_t rightRank_ = TensorTraits<Operand<1, T> >::rank;
129 static constexpr std::ptrdiff_t rightDefectRank_ = rightRank_ - Traits::defectRank_;
137 using LeftOuterPerm = SequenceSlice<Perm, LeftOperandPos>;
138 using RightOuterPerm = OffsetSequence<-leftDefectRank_, SequenceSlice<Perm, RightOperandPos> >;
142 using LeftLookup = SequenceSliceComplement<MakeIndexSequence<leftRank_>, LeftIndexPositions>;
143 using RightLookup = SequenceSliceComplement<MakeIndexSequence<rightRank_>, RightIndexPositions>;
153 using Type = ConditionalType<(N == 0), LeftInnerPerm, RightInnerPerm>;
157 template<std::
size_t N,
class Perm ,
class T>
160 std::enable_if_t<(IsSubordinateTransposition<Perm, T>::value
161 && IsTensorProductExpression<T>::value
162 && (N < Arity<T>::value)
165 using Traits = TensorProductTraits<Operation<T> >;
166 using LeftIndexPositions =
typename Traits::LeftIndexPositions;
167 using RightIndexPositions =
typename Traits::RightIndexPositions;
169 static constexpr std::size_t leftRank_ = TensorTraits<Operand<0, T> >::rank;
170 static constexpr std::size_t leftDefectRank_ = leftRank_ - Traits::defectRank_;
171 static constexpr std::size_t rightRank_ = TensorTraits<Operand<1, T> >::rank;
172 static constexpr std::size_t rightDefectRank_ = rightRank_ - Traits::defectRank_;
181 using FrontOuterPerm = SequenceSlice<Perm, FrontOperandPos>;
182 using LeftOuterPerm = OffsetSequence<-(int)frontRank_, SequenceSlice<Perm, LeftOperandPos> >;
183 using RightOuterPerm = OffsetSequence<-(int)(frontRank_+leftDefectRank_), SequenceSlice<Perm, RightOperandPos> >;
189 using LeftLookup = SequenceSliceComplement<MakeIndexSequence<leftRank_>, LeftIndexPositions>;
190 using RightLookup = SequenceSliceComplement<MakeIndexSequence<rightRank_>, RightIndexPositions>;
202 using Type = ConditionalType<(N == 0), LeftInnerPerm, RightInnerPerm>;
205 template<
class Perm,
class T,
class SFINAE =
void>
206 struct IsSelfTransposed
210 template<
class Perm,
class T>
211 struct IsSelfTransposed<Perm, T,
std::enable_if_t<(!IsDecay<Perm>::value || !IsDecay<T>::value)> >
212 : IsSelfTransposed<std::decay_t<Perm>, std::decay_t<T> >
216 template<
class Perm,
class T>
217 struct IsSelfTransposed<
219 std::enable_if_t<(IsDecay<Perm>::value
221 && IsTensorOperand<T>::value
222 && isSimple(Perm{}))> >
229 template<
class Perm,
class F,
class Dims>
230 struct IsSelfTransposed<Perm, ConstantTensor<F, Dims>,
231 std::enable_if_t<(!isSimple(Perm{})
232 && isInvariant(Dims{}, Perm{})
240 template<
class Perm,
class F,
class Dims>
241 struct IsSelfTransposed<Perm, Eye<Dims, F>,
242 std::enable_if_t<(!isSimple(Perm{})
243 && isInvariant(Dims{}, Perm{})
251 template<std::size_t... Perm,
class Field, std::size_t Rank,
class Dims>
252 struct IsSelfTransposed<Seq<Perm...>, BlockEye<Rank, Dims, Field>,
253 std::enable_if_t<(!isSimple(Seq<Perm...>{})
254 && std::is_same<SequenceProd<Rank, MakeIndexSequence<Dims::size()> >, Seq<Get<Perm, SequenceProd<Rank, MakeIndexSequence<Dims::size()> > >::value...> >::value
260 template<
class Perm,
class Field,
class Dims,
class Index>
261 struct IsSelfTransposed<Perm, KroneckerDelta<Dims, Index, Field>,
262 std::enable_if_t<(!isSimple(Perm{})
263 && isInvariant(Dims{}, Perm{})
264 && isInvariant(Index{}, Perm{})
269 template<
class Perm, std::
size_t N,
class T,
class SFINAE =
void>
270 struct HasSelfTransposedOperand
274 template<
class Perm, std::
size_t N,
class T>
275 struct HasSelfTransposedOperand<
277 std::enable_if_t<IsSelfTransposed<
279 std::enable_if_t<(!Expressions::IsSelfExpression<T>::value
280 && IsExpression<T>::value
281 && Expressions::Arity<T>::value > N
282 && Perm::size() <= TensorTraits<Operand<N, T> >::rank
283 ), Expressions::Operand<N, T> > >::value> >
290 template<
class Perm,
class T>
291 struct IsSelfTransposed<
293 std::enable_if_t<(IsDecay<Perm>::value
296 && IsProductExpression<T>::value
297 && ((TensorTraits<Expressions::Operand<0, T> >::rank == 0
299 HasSelfTransposedOperand<Perm, 1, T>::value)
301 (TensorTraits<Expressions::Operand<1, T> >::rank == 0
303 HasSelfTransposedOperand<Perm, 0, T>::value))
310 template<
class Perm,
class T>
311 struct IsSelfTransposed<
313 std::enable_if_t<(IsDecay<Perm>::value
316 && IsBinaryExpression<T>::value
317 && IsComponentWiseExpression<T>::value
318 && HasSelfTransposedOperand<Perm, 0, T>::value
319 && HasSelfTransposedOperand<Perm, 1, T>::value
329 template<
class Perm,
class T>
330 struct IsSelfTransposed<
332 std::enable_if_t<(IsDecay<Perm>::value
335 && IsProductExpression<T>::value
336 && (TensorTraits<Expressions::Operand<0, T> >::rank > 0
338 TensorTraits<Expressions::Operand<1, T> >::rank > 0)
339 && HasSelfTransposedOperand<TranspositionForOperand<0, Perm, T>, 0, T>::value
340 && HasSelfTransposedOperand<TranspositionForOperand<1, Perm, T>, 1, T>::value
348 template<
class Perm,
class T>
349 struct IsSelfTransposed<
351 std::enable_if_t<(IsDecay<Perm>::value
354 && IsUnaryExpression<T>::value
355 && IsComponentWiseExpression<T>::value
356 && HasSelfTransposedOperand<Perm, 0, T>::value
365 template<
class Perm,
class T>
366 struct IsSelfTransposed<
368 std::enable_if_t<(IsDecay<Perm>::value
371 && IsEinsumExpression<T>::value
372 && IsRuntimeEqualExpression<Operand<0, T> >::value
373 && IsRuntimeEqualExpression<Operand<1, T> >::value
374 && std::is_same<std::decay_t<Operand<0, T> >, std::decay_t<Operand<1, T> > >::value
375 && std::is_same<typename T::LeftIndexPositions, typename T::RightIndexPositions>::value
376 && std::is_same<Perm, SequenceCat<typename T::RightArgs, typename T::LeftArgs> >::value
381 template<std::size_t P0, std::size_t P1, std::size_t... RestPos,
class T>
382 constexpr bool isSelfTransposed(T&& t, Seq<P0, P1, RestPos...> = Seq<P0, P1, RestPos...>{})
384 return IsSelfTransposed<Seq<P0, P1, RestPos...>, T>::value;
388 constexpr bool isSelfTransposed(T&& t)
390 return isSelfTransposed<1,0>(std::forward<T>(t));
constexpr std::size_t size()
Gives the number of elements in tuple-likes and std::integer_sequence.
Definition: size.hh:73
MakeSequence< std::size_t, N, Offset, Stride, Repeat > MakeIndexSequence
Make a sequence of std::size_t elements.
Definition: generators.hh:34
typename ResizedPermutationHelper< Permutation, N >::Type ResizedPermutation
Pad or truncate the permuation at the given size.
Definition: permutation.hh:83
Constant< bool, V > BoolConstant
Short-cut for integral constant of type bool.
Definition: types.hh:48
BoolConstant< false > FalseType
Alias for std::false_type.
Definition: types.hh:110
BoolConstant< true > TrueType
Alias for std::true_type.
Definition: types.hh:107
Definition: transposetraits.hh:40
Construct the induced transposition for operand N if Perm is subordinate to the expression structure ...
Definition: transposetraits.hh:108