teacups 2.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- teacups/__init__.py +0 -0
- teacups/classes.py +42 -0
- teacups/convolution.py +87 -0
- teacups/creators.py +314 -0
- teacups/density_matrices.py +334 -0
- teacups/epr_grid.py +735 -0
- teacups/grid.py +193 -0
- teacups/hamiltonians.py +632 -0
- teacups/hyperfine.py +354 -0
- teacups/input_handler.py +440 -0
- teacups/matrix_tools.py +927 -0
- teacups/memory.py +138 -0
- teacups/multioperator_tools.py +567 -0
- teacups/orientation_dependent_ham.py +182 -0
- teacups/propagation_julia.py +85 -0
- teacups/relaxation.py +263 -0
- teacups/signals_and_processing.py +397 -0
- teacups/simulations.py +177 -0
- teacups/testruns/doublet_transient_nutations.py +53 -0
- teacups/testruns/doublet_with_hyperfines.py +49 -0
- teacups/testruns/psi_rp_early_dynamics.py +59 -0
- teacups/testruns/rp_hf_precursor.py +51 -0
- teacups/testruns/rp_quantum_beats.py +79 -0
- teacups/testruns/tdp_2D_hilbert.py +55 -0
- teacups/testruns/tdp_hf_precursor.py +72 -0
- teacups/testruns/tdp_rqm.py +138 -0
- teacups/testruns/triplet_2D_hilbert.py +51 -0
- teacups/testruns/znp_triplet_asymmetric.py +69 -0
- teacups-2.3.0.dist-info/METADATA +750 -0
- teacups-2.3.0.dist-info/RECORD +33 -0
- teacups-2.3.0.dist-info/WHEEL +5 -0
- teacups-2.3.0.dist-info/licenses/LICENSE +674 -0
- teacups-2.3.0.dist-info/top_level.txt +1 -0
teacups/__init__.py
ADDED
|
File without changes
|
teacups/classes.py
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Sys:
|
|
5
|
+
def __init__(self):
|
|
6
|
+
self.spin_system = "doub"
|
|
7
|
+
self.precursor = "eigen"
|
|
8
|
+
self.population = [1, 0]
|
|
9
|
+
|
|
10
|
+
self.g = [1.95, 2, 2.1]
|
|
11
|
+
|
|
12
|
+
self.width_gauss = 3
|
|
13
|
+
self.sigma_time = 0
|
|
14
|
+
self.decay = 1e-6
|
|
15
|
+
|
|
16
|
+
self.dynamics = None
|
|
17
|
+
self.T_relax_1 = 1e-6
|
|
18
|
+
self.T_relax_2 = 1e-6
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Exp:
|
|
22
|
+
def __init__(self):
|
|
23
|
+
self.B_z = np.linspace(320, 380, 600)
|
|
24
|
+
self.t_scale = [0, 2e-6]
|
|
25
|
+
self.t_points = 60
|
|
26
|
+
self.B_mw = 0.001
|
|
27
|
+
self.freq_mw = 9.75e9
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class SimOpt:
|
|
31
|
+
def __init__(self):
|
|
32
|
+
self.grid_points = 15
|
|
33
|
+
self.grid = "fibonacci"
|
|
34
|
+
self.theta = [np.pi]
|
|
35
|
+
self.phi = [0]
|
|
36
|
+
self.sym = "D2h"
|
|
37
|
+
self.space = "hilbert"
|
|
38
|
+
self.pop_evolution = False
|
|
39
|
+
self.eigval_mode = False
|
|
40
|
+
self.cpu_cores = 1
|
|
41
|
+
self.CUPY = False
|
|
42
|
+
self.extend_t = False
|
teacups/convolution.py
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import scipy.ndimage as snd
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def voigt_convolution(
|
|
6
|
+
sigma_time: float, width: float, spectrum: "np.ndarray", extend_t=False
|
|
7
|
+
) -> "np.ndarray":
|
|
8
|
+
"""
|
|
9
|
+
Calculate the Voigt profile of a Lorentzian function by convolution of the
|
|
10
|
+
existing Lorentzian function and a Gaussian distribution with a given FWHH.
|
|
11
|
+
A 2D-spectrum is convolved with the Gaussian function along its second
|
|
12
|
+
axis, which should be the B-field-axis. Additional the spectrum is convolved
|
|
13
|
+
with a second Gaussian distribution along the first axis (time-axis) for
|
|
14
|
+
simulating the time resoltuion of the signal.
|
|
15
|
+
|
|
16
|
+
Parameters
|
|
17
|
+
----------
|
|
18
|
+
width_time : float
|
|
19
|
+
Standardderivation of the Gauß-Filter, Time resolution of the signal.
|
|
20
|
+
In pixels.
|
|
21
|
+
width : float
|
|
22
|
+
Gaussian line width, standard deviation. In pixels.
|
|
23
|
+
spectrum : np.ndarray
|
|
24
|
+
2D-Array containing values of the ordinate of a spectrum.
|
|
25
|
+
In case of TREPR spectra this would be the intensity for each time and
|
|
26
|
+
magnetic field point. The convolution is carried out along the
|
|
27
|
+
second axis.
|
|
28
|
+
extend_t : bool
|
|
29
|
+
If true the time axis is extended by a zero-baseline with
|
|
30
|
+
5*time_sigma pixels. Default is False.
|
|
31
|
+
|
|
32
|
+
Returns
|
|
33
|
+
-------
|
|
34
|
+
spectrum_conv : np.ndarray
|
|
35
|
+
Array containing convoluted values of the ordinate. In case of TREPR
|
|
36
|
+
spectra this would be the covoluted intensities of the spectrum for
|
|
37
|
+
each magnetic field and time point. Spectrum_conv is computed using the
|
|
38
|
+
convolution alogrithm of SciPy.
|
|
39
|
+
|
|
40
|
+
"""
|
|
41
|
+
pad_t = int(5 * sigma_time)
|
|
42
|
+
spec_pad = np.pad(
|
|
43
|
+
spectrum, ((pad_t, 0), (0, 0)), mode="constant", constant_values=0
|
|
44
|
+
)
|
|
45
|
+
spec_conv_pad = snd.gaussian_filter(spec_pad, [sigma_time, width])
|
|
46
|
+
|
|
47
|
+
if extend_t:
|
|
48
|
+
spectrum_conv = spec_conv_pad
|
|
49
|
+
else:
|
|
50
|
+
spectrum_conv = spec_conv_pad[pad_t:, :]
|
|
51
|
+
|
|
52
|
+
return spectrum_conv
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def extend_time_axis(t: np.ndarray, spec: np.ndarray) -> "np.ndarray":
|
|
56
|
+
"""
|
|
57
|
+
If the time axis is shorter than the time-dimension of the spectrum it gets
|
|
58
|
+
extended by negative values.
|
|
59
|
+
|
|
60
|
+
Parameters
|
|
61
|
+
----------
|
|
62
|
+
t : np.ndarray
|
|
63
|
+
Time axis.
|
|
64
|
+
spec : np.ndarray
|
|
65
|
+
2D-Array containing values of the ordinate of a spectrum.
|
|
66
|
+
In case of TREPR spectra this would be the intensity for each time and
|
|
67
|
+
magnetic field point. The convolution is carried out along the
|
|
68
|
+
second axis.
|
|
69
|
+
|
|
70
|
+
Returns
|
|
71
|
+
-------
|
|
72
|
+
t_extended : np.ndarray
|
|
73
|
+
Time axis. If it has been shorter than the first dimension of spec
|
|
74
|
+
before it is extended by negative values.
|
|
75
|
+
|
|
76
|
+
"""
|
|
77
|
+
if len(t) < spec.shape[0]:
|
|
78
|
+
dt = t[1] - t[0]
|
|
79
|
+
diff = spec.shape[0] - len(t)
|
|
80
|
+
|
|
81
|
+
t_neg = np.arange(-diff, 0) * dt
|
|
82
|
+
t_extended = np.concatenate((t_neg, t))
|
|
83
|
+
|
|
84
|
+
return t_extended
|
|
85
|
+
|
|
86
|
+
else:
|
|
87
|
+
return t
|
teacups/creators.py
ADDED
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import teacups.matrix_tools as mt
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
COMPLEX_TYPE = np.complex64
|
|
5
|
+
FLOAT_TYPE = np.float32
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def create_tensor(
|
|
9
|
+
diag: list, phi: "np.ndarray", theta: "np.ndarray", first_rotation=list()
|
|
10
|
+
) -> object:
|
|
11
|
+
"""
|
|
12
|
+
Setup any tensor. An object of class mt.Tensor is built. Diagonal elements
|
|
13
|
+
are filled into the tensor in its diagonal coordinate frame. If
|
|
14
|
+
first_rotation is not empty, an initial rotation to laboratory frame will
|
|
15
|
+
be carried out. Afterwards the tensor.multirot attribute is built by using
|
|
16
|
+
the tensor.multirotation function with the angle-arrays phi and theta.
|
|
17
|
+
|
|
18
|
+
Parameters
|
|
19
|
+
----------
|
|
20
|
+
diag : list
|
|
21
|
+
A list of the three diagonal elements of the tensor.
|
|
22
|
+
phi : np.ndarray
|
|
23
|
+
Array with the phi values for each angle point.
|
|
24
|
+
theta: np.ndarray
|
|
25
|
+
Array with the theta values for each angle point.
|
|
26
|
+
first_rotation : list
|
|
27
|
+
If a first rotation into laboratory frame is wished, first_rotation
|
|
28
|
+
must be set to a list of the three euler angles phi, theta and psi
|
|
29
|
+
around which the tensor is rotated. If it is empty, no rotation will be
|
|
30
|
+
carried out. Default is an empty list.
|
|
31
|
+
|
|
32
|
+
Returns
|
|
33
|
+
-------
|
|
34
|
+
tensor : object
|
|
35
|
+
Tensor object with initialized tensor and multirot.
|
|
36
|
+
|
|
37
|
+
"""
|
|
38
|
+
tensor = mt.Tensor(np.array(diag))
|
|
39
|
+
|
|
40
|
+
if len(first_rotation) == 0:
|
|
41
|
+
pass
|
|
42
|
+
else:
|
|
43
|
+
angle_list = np.array(first_rotation, dtype=FLOAT_TYPE)
|
|
44
|
+
tensor.rotation(angle_list[0], angle_list[1], angle_list[2])
|
|
45
|
+
tensor.matrix = tensor.rot.astype(FLOAT_TYPE)
|
|
46
|
+
|
|
47
|
+
tensor.multirotation(phi, theta)
|
|
48
|
+
tensor.multirot = tensor.multirot.astype(FLOAT_TYPE)
|
|
49
|
+
return tensor
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def create_zfs_tensor_diagonals(D: float, E: float) -> "np.ndarray":
|
|
53
|
+
"""
|
|
54
|
+
Create an array with three diagonal elements of the zero-field splitting
|
|
55
|
+
(ZFS) tensor. Calculate this values from the zero-field-splitting
|
|
56
|
+
parameters D and E by:
|
|
57
|
+
|
|
58
|
+
.. math::
|
|
59
|
+
-1/3*D+E; -1/3*D-E; 2/3*D.
|
|
60
|
+
|
|
61
|
+
Parameters
|
|
62
|
+
----------
|
|
63
|
+
D : float
|
|
64
|
+
Zero-field-splitting parameter D.
|
|
65
|
+
E : float
|
|
66
|
+
Zero-field-splitting parameter E.
|
|
67
|
+
|
|
68
|
+
Returns
|
|
69
|
+
-------
|
|
70
|
+
diag : np.ndarray
|
|
71
|
+
The three diagonal elements of a ZFS tensor (-1/3*D+E, -1/3*D-E, 2/3*D).
|
|
72
|
+
This is a 1D-array.
|
|
73
|
+
|
|
74
|
+
"""
|
|
75
|
+
diag = np.array([-1 / 3 * D + E, -1 / 3 * D - E, 2 / 3 * D], dtype=FLOAT_TYPE)
|
|
76
|
+
return diag
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def create_dipol_tensor_diagonals(D: float, E: float) -> "np.ndarray":
|
|
80
|
+
"""
|
|
81
|
+
Create an array with three diagonal elements of the dipolar interaction
|
|
82
|
+
tensor of two spin species. Calculate this values from the
|
|
83
|
+
axial dipolar coupling $D$ and the rhombic dipolar coupling $E$ by:
|
|
84
|
+
|
|
85
|
+
.. math::
|
|
86
|
+
D+E; D-E; -2D.
|
|
87
|
+
|
|
88
|
+
Parameters
|
|
89
|
+
----------
|
|
90
|
+
D : float
|
|
91
|
+
Axial dipolar coupling.
|
|
92
|
+
E : float
|
|
93
|
+
Rhombic dipolar coupling.
|
|
94
|
+
|
|
95
|
+
Returns
|
|
96
|
+
-------
|
|
97
|
+
diag : np.ndarray
|
|
98
|
+
The three diagonal elements of a dipol tensor (D+E, -D-E, -2D).
|
|
99
|
+
This is a 1D-array.
|
|
100
|
+
|
|
101
|
+
"""
|
|
102
|
+
diag = np.array([D + E, D - E, -2 * D], dtype=FLOAT_TYPE)
|
|
103
|
+
return diag
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def set_up_tensors(sys: object, cal: object) -> None:
|
|
107
|
+
"""
|
|
108
|
+
Set up all wished tensors for further calculations. The tensors are set up
|
|
109
|
+
for all orientations and are saved as tensor objects.
|
|
110
|
+
Furthermore, if the frame argument in sys is given, the tensors
|
|
111
|
+
will be rotated to an initial frame.
|
|
112
|
+
|
|
113
|
+
Parameters
|
|
114
|
+
----------
|
|
115
|
+
sys : object
|
|
116
|
+
Contains parameters concerning the spin system. This function can use
|
|
117
|
+
the following arguments and returns the tensors:
|
|
118
|
+
g1, g2 (g-tensors of a radical pair) + g1_frame/g2_frame [lists]
|
|
119
|
+
g (g-tensor of a radical) + g_frame [lists]
|
|
120
|
+
g_tri (g-tensor of a triplet) + g_tri_frame [lists]
|
|
121
|
+
D, E (dipole coupling parameters of a coupled spin system) [floats]
|
|
122
|
+
+ D_frame [list], if D, E are not given, they will be set to zero
|
|
123
|
+
D_tri, E_tri (ZFS parameters of a triplet) [floats]
|
|
124
|
+
+ D_tr_frame [list], if D, E are not given, they will be set
|
|
125
|
+
to zero
|
|
126
|
+
cal : object
|
|
127
|
+
Container for calculated tensors. The attributes cal.phi and cal.theta
|
|
128
|
+
(arrays with the angle points on a sphere for rotations) are needed.
|
|
129
|
+
|
|
130
|
+
Attributes
|
|
131
|
+
----------
|
|
132
|
+
cal.g1_tensor : object
|
|
133
|
+
g1-tensor of the radical pair. This is a Tensor object. (optional)
|
|
134
|
+
cal.g2_tensor : object
|
|
135
|
+
g2-tensor of the radical pair. This is a Tensor object. (optional)
|
|
136
|
+
cal.D_tensor : object
|
|
137
|
+
D-tensor of coupled electrons. This is a Tensor object. (optional)
|
|
138
|
+
cal.g_tri_tensor : object
|
|
139
|
+
g-tensor of the triplet precursor. This is a Tensor object.
|
|
140
|
+
cal.D_tri_tensor : object
|
|
141
|
+
D-Tensor of the triplet precursor. This is a Tensor object.
|
|
142
|
+
cal.g_tensor : object
|
|
143
|
+
g-Tensor of a radical. This is a Tensor object. (optional)
|
|
144
|
+
cal.g_iso : float
|
|
145
|
+
Isotropic g-value.
|
|
146
|
+
|
|
147
|
+
Returns
|
|
148
|
+
-------
|
|
149
|
+
None.
|
|
150
|
+
|
|
151
|
+
"""
|
|
152
|
+
if not hasattr(sys, "D"):
|
|
153
|
+
sys.D = 0
|
|
154
|
+
if not hasattr(sys, "E"):
|
|
155
|
+
sys.E = 0
|
|
156
|
+
if not hasattr(sys, "D_tri"):
|
|
157
|
+
sys.D_tri = 0
|
|
158
|
+
if not hasattr(sys, "E_tri"):
|
|
159
|
+
sys.E_tri = 0.01
|
|
160
|
+
|
|
161
|
+
for attr in vars(sys):
|
|
162
|
+
if attr == "g":
|
|
163
|
+
if hasattr(sys, "g_frame"):
|
|
164
|
+
cal.g_tensor = create_tensor(
|
|
165
|
+
sys.g, cal.phi, cal.theta, first_rotation=sys.g_frame
|
|
166
|
+
)
|
|
167
|
+
else:
|
|
168
|
+
cal.g_tensor = create_tensor(sys.g, cal.phi, cal.theta)
|
|
169
|
+
cal.g_iso = 1 / 3 * np.sum(sys.g)
|
|
170
|
+
|
|
171
|
+
elif attr == "g1":
|
|
172
|
+
if hasattr(sys, "g1_frame"):
|
|
173
|
+
cal.g1_tensor = create_tensor(sys.g1, cal.phi, cal.theta, sys.g1_frame)
|
|
174
|
+
else:
|
|
175
|
+
cal.g1_tensor = create_tensor(sys.g1, cal.phi, cal.theta)
|
|
176
|
+
|
|
177
|
+
elif attr == "g2":
|
|
178
|
+
if hasattr(sys, "g2_frame"):
|
|
179
|
+
cal.g2_tensor = create_tensor(sys.g2, cal.phi, cal.theta, sys.g2_frame)
|
|
180
|
+
else:
|
|
181
|
+
cal.g2_tensor = create_tensor(sys.g2, cal.phi, cal.theta)
|
|
182
|
+
cal.g_iso = 1 / 2 * (1 / 3 * np.sum(sys.g1) + 1 / 3 * np.sum(sys.g2))
|
|
183
|
+
|
|
184
|
+
elif attr == "g_tri":
|
|
185
|
+
if hasattr(sys, "g_tri_frame"):
|
|
186
|
+
cal.g_tri_tensor = create_tensor(
|
|
187
|
+
sys.g_tri, cal.phi, cal.theta, sys.g_tri_frame
|
|
188
|
+
)
|
|
189
|
+
else:
|
|
190
|
+
cal.g_tri_tensor = create_tensor(sys.g_tri, cal.phi, cal.theta)
|
|
191
|
+
if hasattr(sys, "g2"):
|
|
192
|
+
pass
|
|
193
|
+
elif hasattr(sys, "g"):
|
|
194
|
+
cal.g_iso = 1 / 2 * (1 / 3 * np.sum(sys.g_tri) + 1 / 3 * np.sum(sys.g))
|
|
195
|
+
else:
|
|
196
|
+
cal.g_iso = 1 / 3 * np.sum(sys.g_tri)
|
|
197
|
+
|
|
198
|
+
elif attr == "D_tri":
|
|
199
|
+
diag = create_zfs_tensor_diagonals(sys.D_tri, sys.E_tri)
|
|
200
|
+
if hasattr(sys, "D_tri_frame"):
|
|
201
|
+
cal.D_tri_tensor = create_tensor(
|
|
202
|
+
diag, cal.phi, cal.theta, sys.D_tri_frame
|
|
203
|
+
)
|
|
204
|
+
else:
|
|
205
|
+
cal.D_tri_tensor = create_tensor(diag, cal.phi, cal.theta)
|
|
206
|
+
|
|
207
|
+
elif attr == "D":
|
|
208
|
+
diag = create_dipol_tensor_diagonals(sys.D, sys.E)
|
|
209
|
+
if hasattr(sys, "D_frame"):
|
|
210
|
+
cal.D_tensor = create_tensor(diag, cal.phi, cal.theta, sys.D_frame)
|
|
211
|
+
|
|
212
|
+
else:
|
|
213
|
+
cal.D_tensor = create_tensor(diag, cal.phi, cal.theta)
|
|
214
|
+
|
|
215
|
+
return None
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def set_up_spinoperator(sys: object, cal: object) -> None:
|
|
219
|
+
"""
|
|
220
|
+
Set up the spin matrix operators for the spin system.
|
|
221
|
+
|
|
222
|
+
Parameters
|
|
223
|
+
----------
|
|
224
|
+
sys : object
|
|
225
|
+
Contains parameters of the spin system. This function needs sys.s which
|
|
226
|
+
is a list of the quantum numbers of the spin system.
|
|
227
|
+
cal : object
|
|
228
|
+
Container for calculated spinoperators. This object may be empty.
|
|
229
|
+
|
|
230
|
+
Attributes
|
|
231
|
+
----------
|
|
232
|
+
cal.s : object
|
|
233
|
+
Spinoperator of the spin system. This is a Spinoperator object.
|
|
234
|
+
|
|
235
|
+
Returns
|
|
236
|
+
-------
|
|
237
|
+
None.
|
|
238
|
+
|
|
239
|
+
"""
|
|
240
|
+
try:
|
|
241
|
+
len(sys.s)
|
|
242
|
+
except TypeError:
|
|
243
|
+
sys.s = [sys.s]
|
|
244
|
+
|
|
245
|
+
if len(sys.s) == 1:
|
|
246
|
+
S = mt.Spinoperator(sys.s[0])
|
|
247
|
+
elif len(sys.s) == 2:
|
|
248
|
+
S = mt.Spinoperator(sys.s[0], sys.s[1])
|
|
249
|
+
S.matrix = S.matrix + S.matrix_coupling_spins[0]
|
|
250
|
+
|
|
251
|
+
cal.s = S
|
|
252
|
+
|
|
253
|
+
return None
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def set_up_observable(sys: object, opt: object, cal: object) -> None:
|
|
257
|
+
"""
|
|
258
|
+
Set up the observable operator for an EPR-Experiment in the singlet-triplet
|
|
259
|
+
basis of the radical pair. Observation direction is y-direction (in case
|
|
260
|
+
of the static magnetic field set in z-direction). The total spin operator
|
|
261
|
+
of a radical pair is taken and transforem to ST-basis. For calculations in
|
|
262
|
+
hilbert-space the operator is given back as a 4x4-matrix. For calculations
|
|
263
|
+
in liouville-space it is given back as a 16x1 vector.
|
|
264
|
+
|
|
265
|
+
Parameters
|
|
266
|
+
----------
|
|
267
|
+
opt : object
|
|
268
|
+
Contains simulation option parameters. This function uses opt.space
|
|
269
|
+
(set either to 'hilbert' or 'liouville'), which defines the space in
|
|
270
|
+
which the calculation is carried out.
|
|
271
|
+
cal : object
|
|
272
|
+
Container for calculated results during the simulation. This function
|
|
273
|
+
uses the total spinoperator cal.s (e.g. built by the function
|
|
274
|
+
set_up_radical_pair_spinoperators).
|
|
275
|
+
|
|
276
|
+
Attributes
|
|
277
|
+
----------
|
|
278
|
+
cal.observable : np.ndarray
|
|
279
|
+
Observable operator (S_y-operator in ST-basis) either as a matrix
|
|
280
|
+
(calculations in hilbert-space) or as a vector (calculations in
|
|
281
|
+
liouville space).
|
|
282
|
+
|
|
283
|
+
Returns
|
|
284
|
+
-------
|
|
285
|
+
None.
|
|
286
|
+
|
|
287
|
+
"""
|
|
288
|
+
|
|
289
|
+
obs = mt.Operator(cal.s.dimension)
|
|
290
|
+
obs.matrix = cal.s.get("y")
|
|
291
|
+
|
|
292
|
+
if sys.spin_system == "rp":
|
|
293
|
+
st_transformation = np.array(
|
|
294
|
+
[
|
|
295
|
+
[1, 0, 0, 0],
|
|
296
|
+
[0, np.sqrt(1 / 2), np.sqrt(1 / 2), 0],
|
|
297
|
+
[0, -np.sqrt(1 / 2), np.sqrt(1 / 2), 0],
|
|
298
|
+
[0, 0, 0, 1],
|
|
299
|
+
],
|
|
300
|
+
dtype=FLOAT_TYPE,
|
|
301
|
+
)
|
|
302
|
+
obs.matrix = st_transformation.T @ obs.matrix @ st_transformation
|
|
303
|
+
|
|
304
|
+
obs.matrix = np.conjugate(obs.matrix.T)
|
|
305
|
+
|
|
306
|
+
if opt.space == "hilbert":
|
|
307
|
+
cal.observable = obs.matrix
|
|
308
|
+
elif opt.space == "liouville":
|
|
309
|
+
obs.build_vector()
|
|
310
|
+
cal.observable = obs.vector
|
|
311
|
+
else:
|
|
312
|
+
print("opt.space has to be either lioville or hilbert")
|
|
313
|
+
|
|
314
|
+
return None
|