Grid 0.7.0
Tensor_exp.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_exp.h
6
7 Copyright (C) 2015
8
9Author: neo <cossu@post.kek.jp>
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_EXP_H
29#define GRID_MATH_EXP_H
30
31#define DEFAULT_MAT_EXP 20
32
34
36// Exponentiate function for scalar, vector, matrix
38
39
41{
43 ret._internal = Exponentiate(r._internal, alpha, Nexp);
44 return ret;
45}
46
48{
50 for (int i = 0; i < N; i++)
51 ret._internal[i] = Exponentiate(r._internal[i], alpha, Nexp);
52 return ret;
53}
54
55
56// Specialisation: Cayley-Hamilton exponential for SU(3)
57#if 0
58template<class vtype, typename std::enable_if< GridTypeMapper<vtype>::TensorLevel == 0>::type * =nullptr>
60{
61 // for SU(3) 2x faster than the std implementation using Nexp=12
62 // notice that it actually computes
63 // exp ( input matrix )
64 // the i sign is coming from outside
65 // input matrix is anti-hermitian NOT hermitian
66 typedef iMatrix<vtype,3> mat;
67 typedef iScalar<vtype> scalar;
68 mat unit(1.0);
69 const Complex one_over_three = 1.0 / 3.0;
70 const Complex one_over_two = 1.0 / 2.0;
71
72 scalar c0, c1, tmp, c0max, theta, u, w;
73 scalar xi0, u2, w2, cosw;
74 scalar fden, h0, h1, h2;
75 scalar e2iu, emiu, ixi0;
76 scalar f0, f1, f2;
77 scalar unity(1.0);
78
79 mat iQ2 = arg*arg*alpha*alpha;
80 mat iQ3 = arg*iQ2*alpha;
81 // sign in c0 from the conventions on the Ta
82 scalar imQ3, reQ2;
83 imQ3 = imag( trace(iQ3) );
84 reQ2 = real( trace(iQ2) );
85 c0 = -imQ3 * one_over_three;
86 c1 = -reQ2 * one_over_two;
87
88 // Cayley Hamilton checks to machine precision, tested
89 tmp = c1 * one_over_three;
90 c0max = 2.0 * pow(tmp, 1.5);
91
92 theta = acos(c0 / c0max) * one_over_three;
93 u = sqrt(tmp) * cos(theta);
94 w = sqrt(c1) * sin(theta);
95
96 xi0 = sin(w) / w;
97 u2 = u * u;
98 w2 = w * w;
99 cosw = cos(w);
100
101 ixi0 = timesI(xi0);
102 emiu = cos(u) - timesI(sin(u));
103 e2iu = cos(2.0 * u) + timesI(sin(2.0 * u));
104
105 h0 = e2iu * (u2 - w2) +
106 emiu * ((8.0 * u2 * cosw) + (2.0 * u * (3.0 * u2 + w2) * ixi0));
107 h1 = e2iu * (2.0 * u) - emiu * ((2.0 * u * cosw) - (3.0 * u2 - w2) * ixi0);
108 h2 = e2iu - emiu * (cosw + (3.0 * u) * ixi0);
109
110 fden = unity / (9.0 * u2 - w2); // reals
111 f0 = h0 * fden;
112 f1 = h1 * fden;
113 f2 = h2 * fden;
114
115 return (f0 * unit + timesMinusI(f1) * arg*alpha - f2 * iQ2);
116}
117#endif
118
119
120// General exponential
121template<class vtype,int N, typename std::enable_if< GridTypeMapper<vtype>::TensorLevel == 0 >::type * =nullptr>
123{
124 // notice that it actually computes
125 // exp ( input matrix )
126 // the i sign is coming from outside
127 // input matrix is anti-hermitian NOT hermitian
128 typedef iMatrix<vtype,N> mat;
129 mat unit(1.0);
130 mat temp(unit);
131 for(int i=Nexp; i>=1;--i){
132 temp *= alpha/RealD(i);
133 temp = unit + temp*arg;
134 }
135 return temp;
136
137}
138
140
141#endif
#define accelerator_inline
accelerator_inline void timesMinusI(Grid_simd2< S, V > &ret, const Grid_simd2< S, V > &in)
accelerator_inline void timesI(Grid_simd2< S, V > &ret, const Grid_simd2< S, V > &in)
accelerator_inline Grid_simd2< S, V > trace(const Grid_simd2< S, V > &arg)
accelerator_inline Grid_simd< S, V > cos(const Grid_simd< S, V > &r)
accelerator_inline Grid_simd< S, V > sin(const Grid_simd< S, V > &r)
accelerator_inline Grid_simd< S, V > acos(const Grid_simd< S, V > &r)
accelerator_inline Grid_simd< S, V > sqrt(const Grid_simd< S, V > &r)
Lattice< vobj > real(const Lattice< vobj > &lhs)
Lattice< vobj > imag(const Lattice< vobj > &lhs)
Lattice< obj > pow(const Lattice< obj > &rhs_i, RealD y)
#define NAMESPACE_BEGIN(A)
Definition Namespace.h:35
#define NAMESPACE_END(A)
Definition Namespace.h:36
uint32_t Integer
Definition Simd.h:58
std::complex< Real > Complex
Definition Simd.h:80
double RealD
Definition Simd.h:61
accelerator_inline iScalar< vtype > Exponentiate(const iScalar< vtype > &r, RealD alpha, Integer Nexp=DEFAULT_MAT_EXP)
Definition Tensor_exp.h:40
#define DEFAULT_MAT_EXP
Definition Tensor_exp.h:31
vtype _internal
vtype _internal[N]