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