DUNE-ACFEM (unstable)

transposetraits.hh
1#ifndef __DUNE_ACFEM_TENSORS_OPERATIONS_TRANSPOSETRAITS_HH__
2#define __DUNE_ACFEM_TENSORS_OPERATIONS_TRANSPOSETRAITS_HH__
3
4#include "../../mpl/compare.hh"
5#include "../../expressions/storage.hh"
6#include "../expressionoperations.hh"
7#include "../modules.hh"
8
9namespace Dune {
10
11 namespace ACFem {
12
17 namespace Tensor {
18
37 template<class Perm, class T, class SFINAE = void>
39 : FalseType
40 {};
41
42 template<class Perm, class T, class SFINAE>
43 struct IsSubordinateTransposition<Perm, T&, SFINAE>
45 {};
46
47 template<class Perm, class T, class SFINAE>
48 struct IsSubordinateTransposition<Perm, T&&, SFINAE>
49 : IsSubordinateTransposition<Perm, std::decay_t<T>, SFINAE>
50 {};
51
52 template<class Perm, class T>
53 struct IsSubordinateTransposition<
54 Perm, T,
55 std::enable_if_t<IsDecay<T>::value && Perm::size() != TensorTraits<T>::rank> >
56 : IsSubordinateTransposition<ResizedPermutation<Perm, TensorTraits<T>::rank>, T>
57 {};
58
62 template<class Perm, class T>
64 Perm, 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
70 )> >
71 : TrueType
72 {};
73
75 template<class Perm, class T>
77 Perm, T,
78 std::enable_if_t<(IsDecay<T>::value
79 && isPermutation(Perm{})
80 // Could be relaxed by using a ResizedPermutation
81 && Perm::size() == TensorTraits<T>::rank
82 && IsEinsumExpression<T>::value
83 )> >
84 : BoolConstant<(isPermutation(SequenceSlice<Perm, typename T::LeftArgs>{})
85 &&
86 isPermutation(SequenceCat<typename T::LeftArgs, SequenceSlice<Perm, typename T::RightArgs> >{}))>
87 {};
88
90 template<class Perm, class T>
92 Perm, T,
93 std::enable_if_t<(IsDecay<T>::value
94 && isPermutation(Perm{})
95 && Perm::size() == TensorTraits<T>::rank
96 && IsTensorProductExpression<T>::value
97 )> >
98 : BoolConstant<(// Defect | RestLeft | RestRight
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> >{}))>
102 {};
103
107 template<std::size_t N, class Perm, class T, class SFINAE = void>
109
110 template<std::size_t N, class Perm, class T>
111 using TranspositionForOperand = typename TranspositionForOperandHelper<N, Perm, T>::Type;
112
114 template<std::size_t N, class PermArg, class T>
116 N, PermArg, T,
117 std::enable_if_t<(IsSubordinateTransposition<PermArg, T>::value
118 && IsEinsumExpression<T>::value
119 && (N < Arity<T>::value)
120 )> >
121 {
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_;
130
131 // Positions of left and right indices in index tuple
132 using LeftOperandPos = MakeIndexSequence<leftDefectRank_>;
135
136 // Parts of the permutation referring to the respective operand
137 using LeftOuterPerm = SequenceSlice<Perm, LeftOperandPos>;
138 using RightOuterPerm = OffsetSequence<-leftDefectRank_, SequenceSlice<Perm, RightOperandPos> >;
139
140 // Construct the lookup tables to map the outer permutations
141 // to the original index posisitions.
142 using LeftLookup = SequenceSliceComplement<MakeIndexSequence<leftRank_>, LeftIndexPositions>;
143 using RightLookup = SequenceSliceComplement<MakeIndexSequence<rightRank_>, RightIndexPositions>;
144
145 // Map the outer permutations to the correct values.
146 using LeftMappedPerm = TransformedSequence<MapSequenceFunctor<LeftLookup>, LeftOuterPerm>;
147 using RightMappedPerm = TransformedSequence<MapSequenceFunctor<RightLookup>, RightOuterPerm>;
148
149 // Now inject the defect positions as identity at the proper locations
152
153 using Type = ConditionalType<(N == 0), LeftInnerPerm, RightInnerPerm>;
154 };
155
157 template<std::size_t N, class Perm , class T>
159 N, Perm, T,
160 std::enable_if_t<(IsSubordinateTransposition<Perm, T>::value
161 && IsTensorProductExpression<T>::value
162 && (N < Arity<T>::value)
163 )> >
164 {
165 using Traits = TensorProductTraits<Operation<T> >;
166 using LeftIndexPositions = typename Traits::LeftIndexPositions;
167 using RightIndexPositions = typename Traits::RightIndexPositions;
168 static constexpr std::size_t frontRank_ = LeftIndexPositions::size();
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_;
173
174 // Positions of left and right indices in index tuple
175 using FrontOperandPos = MakeIndexSequence<frontRank_>;
179
180 // Parts of the permutation referring to the respective operand
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> >;
184
185 // Construct the lookup tables to map the outer permutations
186 // to the original index posisitions. The lookup-table for the
187 // front indices is just LeftIndexPositions
188 // resp. RightIndexPositions
189 using LeftLookup = SequenceSliceComplement<MakeIndexSequence<leftRank_>, LeftIndexPositions>;
190 using RightLookup = SequenceSliceComplement<MakeIndexSequence<rightRank_>, RightIndexPositions>;
191
192 // Map the outer permutations to the correct values.
193 using LeftMappedPerm = TransformedSequence<MapSequenceFunctor<LeftLookup>, LeftOuterPerm>;
194 using LeftMappedFrontPerm = TransformedSequence<MapSequenceFunctor<LeftIndexPositions>, FrontOuterPerm>;
195 using RightMappedPerm = TransformedSequence<MapSequenceFunctor<RightLookup>, RightOuterPerm>;
196 using RightMappedFrontPerm = TransformedSequence<MapSequenceFunctor<RightIndexPositions>, FrontOuterPerm>;
197
198 // Now inject the defect positions as identity at the proper locations
201
202 using Type = ConditionalType<(N == 0), LeftInnerPerm, RightInnerPerm>;
203 };
204
205 template<class Perm, class T, class SFINAE = void>
206 struct IsSelfTransposed
207 : FalseType
208 {};
209
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> >
213 {};
214
216 template<class Perm, class T>
217 struct IsSelfTransposed<
218 Perm, T,
219 std::enable_if_t<(IsDecay<Perm>::value
220 && IsDecay<T>::value
221 && IsTensorOperand<T>::value
222 && isSimple(Perm{}))> >
223 : TrueType
224 {};
225
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{})
233 )> >
234 : TrueType
235 {};
236
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{})
244 )> >
245 : TrueType
246 {};
247
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
255 )> >
256 : TrueType
257 {};
258
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{})
265 )> >
266 : TrueType
267 {};
268
269 template<class Perm, std::size_t N, class T, class SFINAE = void>
270 struct HasSelfTransposedOperand
271 : FalseType
272 {};
273
274 template<class Perm, std::size_t N, class T>
275 struct HasSelfTransposedOperand<
276 Perm, N, T,
277 std::enable_if_t<IsSelfTransposed<
278 Perm,
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> >
284 : TrueType
285 {};
286
290 template<class Perm, class T>
291 struct IsSelfTransposed<
292 Perm, T,
293 std::enable_if_t<(IsDecay<Perm>::value
294 && IsDecay<T>::value
295 && !isSimple(Perm{})
296 && IsProductExpression<T>::value
297 && ((TensorTraits<Expressions::Operand<0, T> >::rank == 0
298 &&
299 HasSelfTransposedOperand<Perm, 1, T>::value)
300 ||
301 (TensorTraits<Expressions::Operand<1, T> >::rank == 0
302 &&
303 HasSelfTransposedOperand<Perm, 0, T>::value))
304 )> >
305 : TrueType
306 {};
307
310 template<class Perm, class T>
311 struct IsSelfTransposed<
312 Perm, T,
313 std::enable_if_t<(IsDecay<Perm>::value
314 && IsDecay<T>::value
315 && !isSimple(Perm{})
316 && IsBinaryExpression<T>::value
317 && IsComponentWiseExpression<T>::value
318 && HasSelfTransposedOperand<Perm, 0, T>::value
319 && HasSelfTransposedOperand<Perm, 1, T>::value
320 )> >
321 : TrueType
322 {};
323
329 template<class Perm, class T>
330 struct IsSelfTransposed<
331 Perm, T,
332 std::enable_if_t<(IsDecay<Perm>::value
333 && IsDecay<T>::value
334 && !isSimple(Perm{})
335 && IsProductExpression<T>::value
336 && (TensorTraits<Expressions::Operand<0, T> >::rank > 0
337 &&
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
341 )> >
342 : TrueType
343 {};
344
348 template<class Perm, class T>
349 struct IsSelfTransposed<
350 Perm, T,
351 std::enable_if_t<(IsDecay<Perm>::value
352 && IsDecay<T>::value
353 && !isSimple(Perm{})
354 && IsUnaryExpression<T>::value
355 && IsComponentWiseExpression<T>::value
356 && HasSelfTransposedOperand<Perm, 0, T>::value
357 )> >
358 : TrueType
359 {};
360
365 template<class Perm, class T>
366 struct IsSelfTransposed<
367 Perm, T,
368 std::enable_if_t<(IsDecay<Perm>::value
369 && IsDecay<T>::value
370 && !isSimple(Perm{})
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
377 )> >
378 : TrueType
379 {};
380
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...>{})
383 {
384 return IsSelfTransposed<Seq<P0, P1, RestPos...>, T>::value;
385 }
386
387 template<class T>
388 constexpr bool isSelfTransposed(T&& t)
389 {
390 return isSelfTransposed<1,0>(std::forward<T>(t));
391 }
392
394
396
398
399 } // NS Tensor
400
402
403 } // NS ACFem
404
405} // NS Dune
406
407#endif // __DUNE_ACFEM_TENSORS_OPERATIONS_TRANSPOSE_HH__
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
TransformSequence< Seq, Sequence< Tout >, F > TransformedSequence
Transform given sequence.
Definition: transform.hh:273
typename InsertAtHelper< Sequence< typename Input::value_type >, Input, Inject, Pos, AssumeSorted >::Type InsertAt
Insert Inject into the sequence Input at the position specified by Pos.
Definition: insertat.hh:87
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
STL namespace.
Definition: transposetraits.hh:40
Construct the induced transposition for operand N if Perm is subordinate to the expression structure ...
Definition: transposetraits.hh:108
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)