@@ -37,18 +37,28 @@ function bloch_redfield_tensor(
3737 U = QuantumObject (rst. vectors, Operator (), H. dimensions)
3838 sec_cutoff = float (sec_cutoff)
3939
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)
4243
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
4646
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
4853 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
5060 else
51- return SU ' * R0 * SU + R1 , U
61+ return L0 + R , U
5262 end
5363end
5464
@@ -86,11 +96,21 @@ function brterm(
8696 fock_basis:: Union{Bool,Val} = Val (false ),
8797)
8898 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)
90105 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
92112 else
93- return term, Qobj (rst . vectors, Operator (), rst . dimensions)
113+ return term, U
94114 end
95115end
96116
@@ -99,7 +119,7 @@ function _brterm(
99119 a_op:: T ,
100120 spectra:: F ,
101121 sec_cutoff:: Real ,
102- fock_basis :: Union{Val{true} ,Val{false} } ,
122+ fock_basis_hamiltonian :: Union{Bool ,Val} ,
103123) where {T<: QuantumObject{Operator} ,F<: Function }
104124 _check_br_spectra (spectra)
105125
@@ -110,9 +130,11 @@ function _brterm(
110130 spectrum = spectra .(skew)
111131
112132 A_mat = U' * a_op. data * U
133+ A_mat_spec = A_mat .* spectrum
134+ A_mat_spec_t = A_mat .* transpose (spectrum)
113135
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
116138
117139 if sec_cutoff != - 1
118140 m_cut = similar (skew)
@@ -124,20 +146,29 @@ function _brterm(
124146 M_cut = @. abs (vec_skew - vec_skew' ) < sec_cutoff
125147 end
126148
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
132168
133169 (sec_cutoff != - 1 ) && (out .*= M_cut)
134170
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)
141172end
142173
143174@doc raw """
0 commit comments