Grid 0.7.0
Tensor_transpose.h
Go to the documentation of this file.
1/*************************************************************************************
2
3 Grid physics library, www.github.com/paboyle/Grid
4
5 Source file: ./lib/tensors/Tensor_transpose.h
6
7 Copyright (C) 2015
8
9Author: Peter Boyle <paboyle@ph.ed.ac.uk>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License along
22 with this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
25 See the full license in the file "LICENSE" in the top level distribution directory
26*************************************************************************************/
27/* END LEGAL */
28#ifndef GRID_MATH_TRANSPOSE_H
29#define GRID_MATH_TRANSPOSE_H
30
32
34// Transpose all indices
36
41
42template<class vtype,int N>
43accelerator_inline typename std::enable_if<isGridTensor<vtype>::value, iMatrix<vtype,N> >::type
45{
47 for(int i=0;i<N;i++){
48 for(int j=0;j<N;j++){
49 ret._internal[i][j] = transpose(arg._internal[j][i]); // NB recurses
50 }}
51 return ret;
52}
53template<class vtype,int N>
54accelerator_inline typename std::enable_if<isGridTensor<vtype>::notvalue, iMatrix<vtype,N> >::type
56{
58 for(int i=0;i<N;i++){
59 for(int j=0;j<N;j++){
60 ret._internal[i][j] = arg._internal[j][i]; // Stop recursion if not a tensor type
61 }}
62 return ret;
63}
64
65template<class vtype>
66accelerator_inline typename std::enable_if<isGridTensor<vtype>::value, iScalar<vtype> >::type
68{
70 ret._internal = transpose(arg._internal); // NB recurses
71 return ret;
72}
73
74template<class vtype>
75accelerator_inline typename std::enable_if<isGridTensor<vtype>::notvalue, iScalar<vtype> >::type
77{
79 ret._internal = arg._internal; // NB recursion stops
80 return ret;
81}
82
83
85// Transpose a specific index; instructive to compare this style of recursion termination
86// to that of adj; which is easiers?
88#if 0
89template<int Level,class vtype,int N> accelerator_inline
90typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,Level>::value, iMatrix<vtype,N> >::type
92{
94 for(int i=0;i<N;i++){
95 for(int j=0;j<N;j++){
96 ret._internal[i][j] = arg._internal[j][i];
97 }}
98 return ret;
99}
100// or not
101template<int Level,class vtype,int N> accelerator_inline
102typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,Level>::notvalue, iMatrix<vtype,N> >::type
104{
106 for(int i=0;i<N;i++){
107 for(int j=0;j<N;j++){
108 ret._internal[i][j] = transposeIndex<Level>(arg._internal[i][j]);
109 }}
110 return ret;
111}
112template<int Level,class vtype> accelerator_inline
113typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,Level>::notvalue, iScalar<vtype> >::type
115{
116 iScalar<vtype> ret;
118 return ret;
119}
120template<int Level,class vtype> accelerator_inline
121typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,Level>::value, iScalar<vtype> >::type
123{
124 return arg;
125}
126#endif
127
129
130#endif
#define accelerator_inline
#define NAMESPACE_BEGIN(A)
Definition Namespace.h:35
#define NAMESPACE_END(A)
Definition Namespace.h:36
std::complex< RealF > ComplexF
Definition Simd.h:78
float RealF
Definition Simd.h:60
std::complex< RealD > ComplexD
Definition Simd.h:79
double RealD
Definition Simd.h:61
accelerator_inline auto transposeIndex(const vtype &arg) -> RemoveCRV(TensorIndexRecursion< Level >::transposeIndex(arg))
accelerator_inline ComplexD transpose(ComplexD &rhs)
vtype _internal[N][N]
vtype _internal