-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsqaIndex.py
201 lines (162 loc) · 6.94 KB
/
sqaIndex.py
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# Copyright 2009-2022 SecondQuantizationAlgebra Developers. All Rights Reserved.
#
# Licensed under the GNU General Public License v3.0;
# you may not use this file except in compliance with the License.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# In addition, any modification or use of this software should
# cite the following paper:
#
# E. Neuscamman, T. Yanai, and G. K.-L. Chan.
# J. Chem. Phys. 130, 124102 (2009)
#
# Author: Eric Neuscamman <[email protected]>
#
# The index class is used to represent a tensor index.
# An index consists of three parts: a name, a list of types, and a bool.
#
# The index's name may be any string.
#
# The bool indicates whether the index is summed over or otherwise is a dummy index whose name may be changed.
# A value of True means that the various operator algebra functions are allowed the change the index's name.
# A value of False means that the index's name may not be changed.
#
# The list of types is actually a list of lists of strings. Each list of strings represents a type group.
# Examples of type groups are the index's spin type or whether the index is core, active, virtual, etc.
# The reason for this format is to evaluate Kronecker delta functions,
# which will evaluate to zero if there is no overlap in any of the two indices' type groups.
#
# For example, if index1 has indexType = [['alpha'], ['core', 'active']] and
# index2 has indexType = [['beta'], ['active']], the Kronecker delta between them will be zero
# because the first type group has no matching strings.
#
# If the first type group had been omitted, then the delta function would not be
# zero because both indices have 'active' as one of the types in the second type group.
# Note that while the type groups can be inputted as a list of lists of strings,
# they are actually stored as a tuple of tuples of strings.
from sqaOptions import options
class index:
"A class for tensor and operator indices."
def __init__(self, name, indexType = (), isSummed = False, userDefined = True):
# Initialize index name
self.name = str(name)
# Initialize index types
indType = []
for l in indexType:
if not ( type(l) in [type([]), type(())] ):
raise TypeError("indexType must be a list or tuple of lists or tuples of strings")
indType.append([])
indType[-1].extend(l)
indType[-1].sort()
# indType.sort()
self.indType = []
for l in indType:
self.indType.append(())
for s in l:
if type(s) != type('a'):
raise TypeError("indexType must be a list or tuple of lists or tuples of strings")
self.indType[-1] = self.indType[-1] + (s,)
self.indType = tuple(self.indType)
# Initialize flag for whether the index is summed over
if type(isSummed) != type(True):
raise TypeError("isSummed must be True or False")
self.isSummed = isSummed
if (type(userDefined) != type(True)) and not isinstance(userDefined, str):
raise TypeError("userDefined must be True or False")
if userDefined is True:
self.userDefined = str(name)
options.add_user_defined_index(str(name))
else:
self.userDefined = userDefined
def __cmp__(self,other):
if (not isinstance(other,index)):
raise ValueError("can only compare index class with other index class objects.")
retval = cmp(self.isSummed, other.isSummed)
if retval != 0:
return retval
retval = cmp(self.name, other.name)
if retval != 0:
return retval
return cmp(self.indType, other.indType)
def tup(self):
"Returns a tuple representation of the index. The return object in unmutable and thus can be used as a dictionary key."
return (self.name, self.indType, self.isSummed, self.userDefined)
def copy(self):
"Returns a deep copy of the index"
return index(self.name, self.indType, self.isSummed, self.userDefined)
def rename(self):
"Rename index according to user defined name."
if isinstance(self.userDefined, str):
self.name = self.userDefined
# SecondQuantizationAlgebra Plus
#
# Functions implemented to automate test index types
#
# Author: Carlos E. V. de Moura <[email protected]>
def is_spin_integrated_index_type(indice_types):
spin_integrated = False
if isinstance(indice_types, index):
indice_types = indice_types.indType
for index_type in indice_types:
if index_type in (options.alpha_type, options.beta_type):
spin_integrated = True
return spin_integrated
def get_spin_index_type(indice_types):
spin_index_types = ''
if isinstance(indice_types, index):
indice_types = indice_types.indType
for index_type in indice_types:
if index_type in (options.alpha_type, options.beta_type):
spin_index_types = index_type
return spin_index_types
def get_spatial_index_type(indice_types):
spatial_index_type = ''
if isinstance(indice_types, index):
indice_types = indice_types.indType
for index_type in indice_types:
if not index_type in (options.alpha_type, options.beta_type):
spatial_index_type = index_type
return spatial_index_type
def is_index_type(indice_types, sqa_index_type):
is_type = False
for index_type in indice_types:
if index_type in sqa_index_type:
is_type = True
return is_type
def is_core_index_type(index_type):
spatial_index_type = get_spatial_index_type(index_type)
is_core_index = False
for core_index_type in (options.core_type, options.cvs_core_type, options.cvs_valence_type):
if is_index_type(spatial_index_type, core_index_type):
is_core_index = True
return is_core_index
def is_cvs_index_type(index_type):
spatial_index_type = get_spatial_index_type(index_type)
is_cvs_index = False
for cvs_index_type in (options.cvs_core_type, options.cvs_valence_type):
if is_index_type(spatial_index_type, cvs_index_type):
is_cvs_index = True
return is_cvs_index
def is_cvs_core_index_type(index_type):
spatial_index_type = get_spatial_index_type(index_type)
return is_index_type(spatial_index_type, options.cvs_core_type)
def is_cvs_valence_index_type(index_type):
spatial_index_type = get_spatial_index_type(index_type)
return is_index_type(spatial_index_type, options.cvs_valence_type)
def is_active_index_type(index_type):
spatial_index_type = get_spatial_index_type(index_type)
return is_index_type(spatial_index_type, options.active_type)
def is_virtual_index_type(index_type):
spatial_index_type = get_spatial_index_type(index_type)
return is_index_type(spatial_index_type, options.virtual_type)
def is_alpha_index_type(index_type):
spin_index_type = get_spin_index_type(index_type)
return is_index_type(spin_index_type, options.alpha_type)
def is_beta_index_type(index_type):
spin_index_type = get_spin_index_type(index_type)
return is_index_type(spin_index_type, options.beta_type)