/
Tensor.py
112 lines (93 loc) · 4.16 KB
/
Tensor.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
#!/usr/bin/env python3
## vi: tabstop=4 shiftwidth=4 softtabstop=4 expandtab
## ---------------------------------------------------------------------
##
## Copyright (C) 2019 by the adcc authors
##
## This file is part of adcc.
##
## adcc 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.
##
## adcc 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 adcc. If not, see <http://www.gnu.org/licenses/>.
##
## ---------------------------------------------------------------------
from .Symmetry import Symmetry
import libadcc
class Tensor(libadcc.Tensor):
def __init__(self, sym_or_mo, space=None,
permutations=None, spin_block_maps=None,
spin_blocks_forbidden=None):
"""Construct an uninitialised Tensor from an :class:`MoSpaces` or
a :class:`Symmetry` object.
More information about the last four, symmetry-related parameters
see the documentation of the :class:`Symmetry` object.
Parameters
----------
sym_or_mo
Symmetry or MoSpaces object
spaces : str, optional
Space of the tensor, can be None if the first argument is
a :class:`Symmetry` object.
permutations : list, optional
List of permutational symmetries of the Tensor.
spin_block_maps : list, optional
List of mappings between spin blocks
spin_blocks_forbidden : list, optional
List of forbidden (i.e. forced-to-zero) spin blocks.
Notes
-----
An :class:`MoSpaces` object is contained in many datastructures
of adcc, including the :class:`AdcMatrix`, the :class:`LazyMp`,
the :class:`ReferenceState` and any solver or ADC results state.
Examples
--------
Construct a symmetric tensor in the "o1o1" (occupied-occupied) spaces:
>>> Tensor(mospaces, "o1o1", permutations=["ij", "ji"])
Construct an anti-symmetric tensor in the "v1v1" spaces:
>>> Tensor(mospaces, "v1v1", permutations=["ab", "-ba"])
Construct a tensor in "o1v1", which maps the alpha-alpha block
anti-symmetrically to the beta-beta block and which has the
other spin blocks set to zero:
>>> Tensor(mospaces, "o1v1", spin_block_maps=[("aa", "bb", -1)],
... spin_blocks_forbidden=["ab", "ba"])
"""
if not isinstance(sym_or_mo, (libadcc.MoSpaces, libadcc.Symmetry)):
raise TypeError("The first argument needs to be a Symmetry or an "
"MoSpaces object.")
if not isinstance(sym_or_mo, libadcc.Symmetry):
if space is None:
raise ValueError("If the first argument to Tensor is no "
"Symmetry object, the second argument (spaces)"
"needs to be given")
sym_or_mo = Symmetry(sym_or_mo, space, permutations,
spin_block_maps, spin_blocks_forbidden)
if space is not None:
if sym_or_mo.space != space:
raise ValueError("Value passed to space needs to agree with "
"space value from Symmetry object.")
super().__init__(sym_or_mo)
def _tensor_select_below_absmax(tensor, tolerance):
"""
Select the absolute maximal values in the tensor,
which are below the given tolerance.
"""
n = min(10, tensor.size)
res = []
while n <= tensor.size:
res = tensor.select_n_absmax(n)
minampl = min(abs(r[1]) for r in res)
if minampl < tolerance:
break
else:
n = max(n + 1, min(tensor.size, 2 * n))
return [r for r in res if abs(r[1]) >= tolerance]
Tensor.select_below_absmax = _tensor_select_below_absmax