Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// TensorIndex class definition file -*- C++ -*-
/* Copyright 2008 Mike Williams (mwill@jlab.org)
*
* This file is part of qft++.
*
* qft++ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* qft++ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with qft++. If not, see <http://www.gnu.org/licenses/>.
*/
// Author: Mike Williams
// Author: Matt Shepherd
#ifndef _TensorIndex_h
#define _TensorIndex_h
//_____________________________________________________________________________
#include <cassert>
#include <iostream>
using namespace std;
//_____________________________________________________________________________
/** @file TensorIndex.h
* @brief TensorIndex class definition file.
*/
//_____________________________________________________________________________
/** @class TensorIndex
* @author Mike Williams
* @author Matt Shepherd
*
* @brief A class that converts \f$(\mu,\nu,...)\f$ to an index for Tensor.
*
* This class is a utility class used by Tensor. Its current implementation is
* limited to tensors of rank 15 or less (well above current memory
* capacities).
* The elements of Tensor<type> T(rank) can be accessed via
* TensorIndex index(rank) by simply calling T(index).
*
* <b> Example Usage </b>
*
* <!--
* TensorIndex index(this->Rank());
* while(index.IsValid()){
* (*this)(index) "some operations ...";
* ++index;
* }
* -->
* \include TensorIndex.ex
*
* Note: Indicies are t = 0, x = 1, y = 2 and z = 3
*/
//_____________________________________________________________________________
class TensorIndex {
private:
unsigned int _rank; ///< Tensor rank this deals with
int _index; ///< Index to Tensor vector of elements
public:
// create/copy/destroy
TensorIndex() : _rank(0),_index(0){/** Default Constructor */}
/// Constructor (connect with rank @a rank tensor)
TensorIndex(unsigned int __rank) : _index(0){
assert( __rank < 16 );
_rank = __rank;
}
virtual ~TensorIndex() {/** Destructor */}
// operators:
/// Returns the tensor index value for @a level
inline int operator[](unsigned int __level) const {
return ((_index >> (__level << 1 ) ) & 0x3);
}
/// Returns the current index
inline int operator()() const {return _index;}
/** Prefix step up incrementer.
*
* If TensorIndex index(rank) is defined, then ++index steps up index
* to the next valid tensor index.
*
* Example: If TensorIndex index(3) = (0,2,1), then ++index = (0,2,2)).
*
* note: Postfix incrementer, index++, is also defined.
*/
TensorIndex& operator++(){ _index++; return (*this); }
/// Postfix step up incrementer (see operator++()).
inline TensorIndex& operator++(int){
return (++(*this));
}
/** Prefix step down incrementer.
*
* If TensorIndex index(rank) is defined, then --index steps down index
* to the next valid tensor index.
*
* Example: For TensorIndex index(3) = (0,2,1), --index = (0,2,0).
*
* note: Postfix incrementer, index--, is also defined.
*/
TensorIndex& operator--(){ _index--; return (*this);}
/// Postfix step down incrementer (see operator--()).
inline TensorIndex& operator--(int){
return (--(*this));
}
// functions:
/// Returns the number of entries (coresponds to tensor rank)
inline int Size() const {return _rank;}
/// Adjust the rank
inline void Resize(unsigned int __rank) {
assert(__rank < 16 );
_rank = __rank;
}
/// Set the index value
inline void SetIndex(unsigned int __i,unsigned int __value){
//assert(__value < 4 && __i < _rank );
_index = (_index & ~(0x3 << (__i << 1))) + (__value << (__i << 1));
}
/// Checks to see if the current tensor index stored is a valid index.
inline bool IsValid() const {
if( ( _index >> ( _rank << 1 ) ) != 0 ) return false;
return true;
}
/// Resets all indicies in this object to 0.
inline void Reset() {_index = 0;}
/** Print to screen the current set of indicies.
* Format is: \f$ (\mu,\nu,\rho,...,\pi) \f$
*/
void Print(ostream &__os = cout);
};
//_____________________________________________________________________________
#endif /* _TensorIndex_H */