@@ -37,18 +37,28 @@ function bloch_redfield_tensor(
37
37
U = QuantumObject (rst. vectors, Operator (), H. dimensions)
38
38
sec_cutoff = float (sec_cutoff)
39
39
40
- # in fock basis
41
- R0 = liouvillian (H, c_ops)
40
+ H_new = getVal (fock_basis) ? H : QuantumObject (Diagonal (rst. values), Operator (), H. dimensions)
41
+ c_ops_new = isnothing (c_ops) ? nothing : map (x -> getVal (fock_basis) ? x : U' * x * U, c_ops)
42
+ L0 = liouvillian (H_new, c_ops_new)
42
43
43
- # set fock_basis=Val(false) and change basis together at the end
44
- R1 = 0
45
- isempty (a_ops) || (R1 += mapreduce (x -> _brterm (rst, x[1 ], x[2 ], sec_cutoff, Val (false )), + , a_ops))
44
+ # Check whether we can rotate the terms to the eigenbasis directly in the Hamiltonian space
45
+ fock_basis_hamiltonian = getVal (fock_basis) && sec_cutoff == - 1
46
46
47
- SU = sprepost (U, U' ) # transformation matrix from eigen basis back to fock basis
47
+ R = isempty (a_ops) ? 0 : sum (x -> _brterm (rst, x[1 ], x[2 ], sec_cutoff, fock_basis_hamiltonian), a_ops)
48
+
49
+ # If in fock basis, we need to transform the terms back to the fock basis
50
+ # Note: we can transform the terms in the Hamiltonian space only if sec_cutoff is -1
51
+ # otherwise, we need to use the SU superoperator below to transform the entire Liouvillian
52
+ # at the end, due to the action of M_cut
48
53
if getVal (fock_basis)
49
- return R0 + SU * R1 * SU'
54
+ if fock_basis_hamiltonian
55
+ return L0 + R # Already rotated in the Hamiltonian space
56
+ else
57
+ SU = sprepost (U, U' )
58
+ return L0 + SU * R * SU'
59
+ end
50
60
else
51
- return SU ' * R0 * SU + R1 , U
61
+ return L0 + R , U
52
62
end
53
63
end
54
64
@@ -86,11 +96,21 @@ function brterm(
86
96
fock_basis:: Union{Bool,Val} = Val (false ),
87
97
)
88
98
rst = eigenstates (H)
89
- term = _brterm (rst, a_op, spectra, sec_cutoff, makeVal (fock_basis))
99
+ U = QuantumObject (rst. vectors, Operator (), H. dimensions)
100
+
101
+ # Check whether we can rotate the terms to the eigenbasis directly in the Hamiltonian space
102
+ fock_basis_hamiltonian = getVal (fock_basis) && sec_cutoff == - 1
103
+
104
+ term = _brterm (rst, a_op, spectra, sec_cutoff, fock_basis_hamiltonian)
90
105
if getVal (fock_basis)
91
- return term
106
+ if fock_basis_hamiltonian
107
+ return term # Already rotated in the Hamiltonian space
108
+ else
109
+ SU = sprepost (U, U' )
110
+ return SU * term * SU'
111
+ end
92
112
else
93
- return term, Qobj (rst . vectors, Operator (), rst . dimensions)
113
+ return term, U
94
114
end
95
115
end
96
116
@@ -99,7 +119,7 @@ function _brterm(
99
119
a_op:: T ,
100
120
spectra:: F ,
101
121
sec_cutoff:: Real ,
102
- fock_basis :: Union{Val{true} ,Val{false} } ,
122
+ fock_basis_hamiltonian :: Union{Bool ,Val} ,
103
123
) where {T<: QuantumObject{Operator} ,F<: Function }
104
124
_check_br_spectra (spectra)
105
125
@@ -110,9 +130,11 @@ function _brterm(
110
130
spectrum = spectra .(skew)
111
131
112
132
A_mat = U' * a_op. data * U
133
+ A_mat_spec = A_mat .* spectrum
134
+ A_mat_spec_t = A_mat .* transpose (spectrum)
113
135
114
- ac_term = (A_mat .* spectrum) * A_mat
115
- bd_term = A_mat * (A_mat .* trans (spectrum))
136
+ ac_term = A_mat_spec * A_mat
137
+ bd_term = A_mat * A_mat_spec_t
116
138
117
139
if sec_cutoff != - 1
118
140
m_cut = similar (skew)
@@ -124,20 +146,29 @@ function _brterm(
124
146
M_cut = @. abs (vec_skew - vec_skew' ) < sec_cutoff
125
147
end
126
148
127
- out =
128
- 0.5 * (
129
- + _sprepost (A_mat .* trans (spectrum), A_mat) + _sprepost (A_mat, A_mat .* spectrum) - _spost (ac_term, Id) -
130
- _spre (bd_term, Id)
131
- )
149
+ # Rotate the terms to the eigenbasis if possible
150
+ if getVal (fock_basis_hamiltonian)
151
+ A_mat = U * A_mat * U'
152
+ A_mat_spec = U * A_mat_spec * U'
153
+ A_mat_spec_t = U * A_mat_spec_t * U'
154
+ ac_term = U * ac_term * U'
155
+ bd_term = U * bd_term * U'
156
+ end
157
+
158
+ # Remove small values before passing in the Liouville space
159
+ if settings. auto_tidyup
160
+ tidyup! (A_mat)
161
+ tidyup! (A_mat_spec)
162
+ tidyup! (A_mat_spec_t)
163
+ tidyup! (ac_term)
164
+ tidyup! (bd_term)
165
+ end
166
+
167
+ out = (_sprepost (A_mat_spec_t, A_mat) + _sprepost (A_mat, A_mat_spec) - _spost (ac_term, Id) - _spre (bd_term, Id)) / 2
132
168
133
169
(sec_cutoff != - 1 ) && (out .*= M_cut)
134
170
135
- if getVal (fock_basis)
136
- SU = _sprepost (U, U' )
137
- return QuantumObject (SU * out * SU' , SuperOperator (), rst. dimensions)
138
- else
139
- return QuantumObject (out, SuperOperator (), rst. dimensions)
140
- end
171
+ return QuantumObject (out, SuperOperator (), rst. dimensions)
141
172
end
142
173
143
174
@doc raw """
0 commit comments