qflux 0.0.1__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.

Potentially problematic release.


This version of qflux might be problematic. Click here for more details.

Files changed (38) hide show
  1. qflux/GQME/__init__.py +7 -0
  2. qflux/GQME/dynamics_GQME.py +438 -0
  3. qflux/GQME/params.py +62 -0
  4. qflux/GQME/readwrite.py +119 -0
  5. qflux/GQME/tdvp.py +233 -0
  6. qflux/GQME/tt_tfd.py +448 -0
  7. qflux/__init__.py +5 -0
  8. qflux/closed_systems/__init__.py +17 -0
  9. qflux/closed_systems/classical_methods.py +427 -0
  10. qflux/closed_systems/custom_execute.py +22 -0
  11. qflux/closed_systems/hamiltonians.py +88 -0
  12. qflux/closed_systems/qubit_methods.py +266 -0
  13. qflux/closed_systems/spin_dynamics_oo.py +371 -0
  14. qflux/closed_systems/spin_propagators.py +300 -0
  15. qflux/closed_systems/utils.py +205 -0
  16. qflux/open_systems/__init__.py +2 -0
  17. qflux/open_systems/dilation_circuit.py +183 -0
  18. qflux/open_systems/numerical_methods.py +303 -0
  19. qflux/open_systems/params.py +29 -0
  20. qflux/open_systems/quantum_simulation.py +360 -0
  21. qflux/open_systems/trans_basis.py +121 -0
  22. qflux/open_systems/walsh_gray_optimization.py +311 -0
  23. qflux/typing/__init__.py +0 -0
  24. qflux/typing/examples.py +24 -0
  25. qflux/utils/__init__.py +0 -0
  26. qflux/utils/io.py +16 -0
  27. qflux/utils/logging_config.py +61 -0
  28. qflux/variational_methods/__init__.py +1 -0
  29. qflux/variational_methods/qmad/__init__.py +0 -0
  30. qflux/variational_methods/qmad/ansatz.py +64 -0
  31. qflux/variational_methods/qmad/ansatzVect.py +61 -0
  32. qflux/variational_methods/qmad/effh.py +75 -0
  33. qflux/variational_methods/qmad/solver.py +356 -0
  34. qflux-0.0.1.dist-info/METADATA +144 -0
  35. qflux-0.0.1.dist-info/RECORD +38 -0
  36. qflux-0.0.1.dist-info/WHEEL +5 -0
  37. qflux-0.0.1.dist-info/licenses/LICENSE +674 -0
  38. qflux-0.0.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,75 @@
1
+ import numpy as np
2
+ from scipy.linalg import expm, kron
3
+
4
+
5
+ def vectorize_comm(A):
6
+ # Create an identity matrix with the same dimension as A
7
+ iden = np.eye(A.shape[0])
8
+ # Compute the vectorized commutator [A, .] as the Kronecker product
9
+ return kron(iden, A) - kron(A.T, iden)
10
+
11
+ class VectorizedEffectiveHamiltonian_class:
12
+ def __init__(self, He, Ha):
13
+ self.He = He
14
+ self.Ha = Ha
15
+
16
+ def VectorizedEffectiveHamiltonian(H, gamma, lind):
17
+ # Create an identity matrix with the same dimension as H
18
+ iden = np.eye(H.shape[0])
19
+ # Get the dimension of H
20
+ d = H.shape[0]
21
+ # Compute the vectorized commutator for the Hamiltonian H
22
+ vec_H = vectorize_comm(H)
23
+ # Initialize the result matrix with zeros (complex type)
24
+ res = np.zeros((d**2, d**2), dtype=np.complex128)
25
+
26
+ # Compute the conjugate of the Lindblad operator
27
+ L_conj = lind.conj()
28
+ L_dagger_L = L_conj.T @ lind
29
+ # Compute the Lindblad contribution to the effective Hamiltonian
30
+ res -= gamma * (kron(L_conj, lind) - (kron(iden, L_dagger_L) + kron(L_dagger_L.T, iden)) / 2)
31
+
32
+ # Return an instance of the VectorizedEffectiveHamiltonian_class with vec_H and res
33
+ return VectorizedEffectiveHamiltonian_class(vec_H, res)
34
+
35
+ class EffectiveHamiltonian_class:
36
+ def __init__(self, He, Ha, Llist, LdL):
37
+ self.He = He # Hermitian part
38
+ self.Ha = Ha # Anti-Hermitian part
39
+ self.Llist = Llist # List of Lindblad operators
40
+ self.LdL = LdL # List of L†L
41
+
42
+ def EffectiveHamiltonian( mats, Llist):
43
+ """
44
+ Create an EffectiveHamiltonian object based on provided parameters.
45
+ :param mats: List of matrices (Hamiltonian terms).
46
+ :param Llist: List of lists of Lindblad operators.
47
+ :return: An instance of EffectiveHamiltonian_class.
48
+ """
49
+ # Directly use the input matrices as the Hermitian part (assuming they are Hermitian)
50
+ He = sum(mats) # Sum of Hamiltonian terms as Hermitian part
51
+ Ha = 0.0 # Initialize anti-Hermitian part
52
+ LdL = [] # Initialize the list for Lindblad operator products
53
+
54
+ for LL in Llist:
55
+ for L in LL:
56
+ L_dagger_L = (L.conj().T @ L)
57
+
58
+ LdL.append(L_dagger_L) # Append to LdL list
59
+ Ha += L_dagger_L # Sum for the anti-Hermitian part
60
+
61
+ # Return the Effective Hamiltonian object
62
+ return EffectiveHamiltonian_class(He, 0.5 * Ha, [L for LL in Llist for L in LL], LdL)
63
+
64
+ # Helper methods that align with the Julia logic
65
+ def herm(H, t):
66
+ return H.He(t) # Assuming He is callable with t
67
+
68
+ def antiherm(H):
69
+ return H.Ha
70
+
71
+ def get_LdL(H):
72
+ return H.LdL
73
+
74
+ def get_L(H):
75
+ return H.Llist
@@ -0,0 +1,356 @@
1
+ import numpy as np
2
+ from itertools import combinations, product
3
+ from scipy.linalg import expm, kron
4
+ from numpy.random import rand
5
+ random_numbers = np.random.uniform(low=10000, high=99999)
6
+ np.random.seed(int(random_numbers))
7
+ from .ansatz import *
8
+ from .ansatzVect import *
9
+
10
+ # Helper Functions for evolution
11
+ # def tag(A):
12
+ # return A.tag if A else None #!!!!!!!a.any or a.all??
13
+ def tag(A):
14
+ return getattr(A, 'tag', None) if A is not None else None
15
+
16
+
17
+ def aexp(A, theta):
18
+ return expm(-1j * theta * A.mat / 2)
19
+
20
+ def add_A(A, P):
21
+ A.A.append(P)
22
+ A.theta = np.append(A.theta, 0)
23
+
24
+ def lmul(A, ψ):
25
+ # print("ehrerw:",A)
26
+ # print("amat:",np.shape(A.mat))
27
+ # print("her in lmul",A.mat @ ψ)
28
+ return A.mat @ ψ
29
+
30
+ def update_theta(ansatz, dtheta, dt):
31
+ ansatz.theta = ansatz.theta + dtheta * dt
32
+
33
+ def partial_theta(A):
34
+ len_A = len(A.A)
35
+ ψ = A.ref.copy()
36
+ res = []
37
+ for i in range(len_A):
38
+ ψ = aexp(A.A[i], A.theta[i]) @ ψ
39
+ ψt = -0.5j * lmul(A.A[i], ψ)
40
+ for j in range(i + 1, len_A):
41
+ ψt = aexp(A.A[j], A.theta[j]) @ ψt
42
+ res.append(ψt)
43
+ return res
44
+
45
+ def build_m(ψ, dψ):
46
+ l = len(dψ)
47
+ res = np.zeros((l, l))
48
+ ψ = ψ[:, np.newaxis] if len(ψ.shape) == 1 else ψ
49
+
50
+ for μ in range(l):
51
+ for ν in range(l):
52
+ res[μ, ν] = 2 * np.real(dψ[μ].T.conj() @ dψ[ν] + ψ.T.conj() @ dψ[μ] @ ψ.T.conj() @ dψ[ν])
53
+ return res
54
+
55
+ def update_m(m, dψa, ψ, dψ):
56
+ l = m.shape[0]
57
+ mp = np.zeros((l + 1, l + 1))
58
+ dψa = dψa[:, np.newaxis]
59
+ ψ = ψ[:, np.newaxis]
60
+ mp[l, l] = 2 * np.real((dψa.T.conj() @ dψa + ψ.T.conj() @ dψa @ ψ.T.conj() @ dψa).item())
61
+ mp[:l, :l] = m
62
+ for μ in range(l):
63
+ temp = 2 * np.real(dψ[μ].T.conj() @ dψa + ψ.T.conj() @ dψ[μ] @ ψ.T.conj() @ dψa)
64
+ mp[μ, l] = temp.item()
65
+ mp[l, μ] = temp.item()
66
+ return mp
67
+
68
+ def build_v(ψ, dψ, He, Ha):
69
+ L = -1j * (He - 1j * Ha)
70
+ l = len(dψ)
71
+ ψ = ψ[:, np.newaxis] if len(ψ.shape) == 1 else ψ
72
+ res = np.zeros(l)
73
+ for μ in range(l):
74
+ res[μ] = 2 * np.real((dψ[μ].T.conj() @ L @ ψ + dψ[μ].T.conj() @ ψ @ ψ.T.conj() @ L.T.conj() @ ψ).item())
75
+ return res
76
+
77
+ def update_v(v, dψₐ, ψ, He, Ha):
78
+ L = -1j * (He - 1j * Ha)
79
+ l = len(v)
80
+ dψₐ = dψₐ[:, np.newaxis]
81
+ ψ = ψ[:, np.newaxis]
82
+ vp = np.zeros(l + 1)
83
+ vp[:l] = v
84
+ vp[l] = 2 * np.real((dψₐ.T.conj() @ L @ ψ + dψₐ.T.conj() @ ψ @ ψ.T.conj() @ L.T.conj() @ ψ).item())
85
+ return vp
86
+
87
+ def lin_solve(m, v, λ=1e-4):
88
+ A = m.T @ m
89
+ try:
90
+ xλ = np.linalg.solve(A + λ**2 * np.eye(A.shape[0]), m.T @ v)
91
+ except np.linalg.LinAlgError:
92
+ xλ = np.linalg.lstsq(A + λ**2 * np.eye(A.shape[0]), m.T @ v, rcond=None)[0]
93
+ return xλ, 2 * v.T @ xλ - xλ.T @ m @ xλ
94
+
95
+ def get_newest_A(A):
96
+ return A.A[-1] if A.A else None
97
+
98
+ def update_state(A):
99
+ if A.A:
100
+ state = A.ref.copy()
101
+ for i in range(len(A.A)):
102
+ state = aexp(A.A[i], A.theta[i]) @ state
103
+ A.state = state
104
+ else:
105
+ A.state = A.ref
106
+
107
+ def set_ref(A, ref):
108
+ A.ref = ref
109
+
110
+ def reset(A):
111
+ A.theta = np.array([])
112
+ A.A = []
113
+ update_state(A)
114
+
115
+ class Result:
116
+ def __init__(self, t, psi, energy, pop, theta, A, jump_t, jump_L, status):
117
+ self.t = t
118
+ self.psi = psi
119
+ self.energy = energy # Add energy attribute
120
+ self.pop = pop
121
+ self.theta = theta
122
+ self.A = A
123
+ self.jump_t = jump_t
124
+ self.jump_L = jump_L
125
+ self.status = status
126
+
127
+ def __repr__(self):
128
+ return f"Result(t={self.t}, psi={self.psi}, energy={self.energy}, pop={self.pop}, theta={self.theta}, A={self.A}, jump_t={self.jump_t}, jump_L={self.jump_L}, status={self.status})"
129
+
130
+ class AVQDSol:
131
+ def __init__(self, t, u, θ, A, jump_L, jump_t, status=0, norm=[]):
132
+ self.t = t
133
+ self.u = u
134
+ self.θ = θ
135
+ self.A = A
136
+ self.jump_L = jump_L
137
+ self.jump_t = jump_t
138
+ self.status = status
139
+ self.norm = norm
140
+
141
+ def one_step(A, He, Ha, dt):
142
+
143
+ relrcut = A.relrcut
144
+ psi_ = A.state
145
+ dpsi_ = partial_theta(A)
146
+ M = build_m(psi_, dpsi_)
147
+ V = build_v(psi_, dpsi_, He, Ha)
148
+ dtheta, vmv = lin_solve(M, V)
149
+ vmvMax = vmv
150
+ Mtmp = M
151
+ Vtmp = V
152
+ dthetatmp = dtheta
153
+ opTmp = None
154
+ dpsi_ₐTmp = None
155
+ add_flag = True
156
+
157
+ while add_flag:
158
+ # print("here in onestep While")
159
+ tagTmp = None
160
+ # print("Ansatz pool:",A.pool)
161
+ for op in A.pool:
162
+ # print("opertaro from pool:",(op.tag))
163
+ if tag(get_newest_A(A)) == tag(op):
164
+ # print("here in get newest_A")
165
+ continue
166
+ # print("here in op for loop")
167
+ dpsi_ₐ = -0.5j * lmul(op, psi_)
168
+
169
+ Mop = update_m(M, dpsi_ₐ, psi_, dpsi_)
170
+ # print("Mop:",Mop)
171
+ Vop = update_v(V, dpsi_ₐ, psi_, He, Ha)
172
+ dthetaop, vmvOp = lin_solve(Mop, Vop)
173
+ # print("berfore the if:","vmvOp:",vmvOp, "vmvMax:",vmvMax)
174
+
175
+ if vmvOp > vmvMax:
176
+ # print("vmvOp:",vmvOp, "vmvMax:",vmvMax)
177
+
178
+ Mtmp = Mop
179
+ Vtmp = Vop
180
+ vmvMax = vmvOp
181
+ dthetatmp = dthetaop
182
+ opTmp = op
183
+ tagTmp = tag(op)
184
+ # print("tagTmp:",tagTmp)
185
+ dpsi_ₐTmp = dpsi_ₐ
186
+ # print("vmvMax - vmv:",vmvMax-vmv)
187
+ add_flag = vmvMax - vmv >= relrcut
188
+
189
+
190
+
191
+ if tagTmp is not None and add_flag:
192
+
193
+ add_A(A, opTmp)
194
+ vmv = vmvMax
195
+ M = Mtmp
196
+ V = Vtmp
197
+ dtheta = dthetatmp
198
+ dpsi_.append(dpsi_ₐTmp)
199
+
200
+ update_theta(A, dtheta, dt)
201
+ # print("Ansatz:",A.theta)
202
+ update_state(A)
203
+
204
+
205
+ def solve_avq_traj(H, A, tspan, dt, save_state=True, save_everystep=True):
206
+ # Store initial reference state for reinitialization
207
+ ref_init = A.ref.copy()
208
+ update_state(A)
209
+
210
+ # Initialize time and recorder lists
211
+ t = tspan[0]
212
+ t_list = []
213
+ u_list = []
214
+ theta_list = []
215
+ A_list = []
216
+ jump_L_list = []
217
+ jump_t_list = []
218
+
219
+ # Break flag for error handling
220
+ break_flag = False
221
+ Gamma = 0 # Jump recorder
222
+ q = rand() # Random number for quantum jump
223
+ # print("expo:",np.exp(-Gamma))
224
+ # print("random q:", q)
225
+
226
+ if save_everystep:
227
+ t_list.append(t)
228
+ theta_list.append(A.theta.copy())
229
+
230
+ A_list.append([tag(a) for a in A.A])
231
+ if save_state:
232
+ u_list.append(A.state.copy())
233
+
234
+ # Main evolution loop
235
+ # This loop performs the simulation of quantum system evolution over a set time span.
236
+ # It integrates the system state forward in time while handling both deterministic
237
+ # evolution and stochastic quantum jumps.
238
+
239
+ while t + dt <= tspan[1]: # Loop over the total time span with step size dt
240
+ # print("timestep:", dt) # Print current time step size for monitoring
241
+ He = H.He # Extract Hermitian Hamiltonian component for deterministic evolution
242
+ Ha = H.Ha # Extract Antihermitian Hamiltonian component for jump handling
243
+
244
+ if np.exp(-Gamma) > q: # Check if no quantum jump occurs, based on jump probability threshold
245
+ try:
246
+ one_step(A, He, Ha, dt) # Perform deterministic evolution for one time step
247
+ except Exception: # In case of failure, exit the loop with a flag
248
+ break_flag = True
249
+ break
250
+ psi_ = A.state # Update the current state of the system
251
+ Gamma += 2 * np.real(psi_.T.conj() @ Ha @ psi_) * dt # Update accumulated Gamma for jump probability
252
+
253
+ if save_everystep: # Option to save state at every time step
254
+ t_list.append(t + dt) # Save current time
255
+ theta_list.append(A.theta.copy()) # Save current ansatz parameters
256
+ A_list.append([tag(a) for a in A.A]) # Save current state of ansatz components
257
+
258
+ else: # Quantum jump occurs
259
+ psi_ = A.state # Get current state before jump
260
+
261
+ # Compute the probabilities for different jump operators
262
+ weights = np.array([np.real(psi_.T.conj() @ LdL @ psi_) for LdL in H.LdL])
263
+
264
+ # Randomly choose a jump operator based on computed probabilities
265
+ L_index = np.random.choice([i for i in range(np.shape(H.Llist)[0])], p=weights/weights.sum())
266
+ L = H.Llist[L_index] # Select corresponding jump operator
267
+
268
+ # Apply the jump operator to the state and normalize it
269
+ psi_n = L @ psi_ / np.linalg.norm(L @ psi_)
270
+
271
+ # Record the jump event details (time and operator used)
272
+ jump_t_list.append(t)
273
+ jump_L_list.append(tag(L))
274
+
275
+ # Record the state and parameters post-jump
276
+ t_list.append(t + dt)
277
+ set_ref(A, psi_n) # Update the state with post-jump state
278
+ reset(A) # Reset the ansatz parameters after jump
279
+
280
+ # Save updated ansatz parameters post-jump
281
+ theta_list.append(A.theta.copy())
282
+ A_list.append([tag(a) for a in A.A])
283
+
284
+ # Reset the jump probability accumulator
285
+ Gamma = 0
286
+ q = rand() # Generate a new random number for the next jump check
287
+
288
+ # Optionally save the state at each time step
289
+ if save_state:
290
+ u_list.append(A.state.copy()) # Store the current state
291
+
292
+ # Increment the simulation time by dt
293
+ t += dt
294
+
295
+
296
+ # Final check for status if no errors occurred
297
+ if not break_flag:
298
+ if (not jump_t_list or not np.isclose(t, jump_t_list[-1])) and not save_everystep:
299
+ theta_list.append(A.theta.copy())
300
+ A_list.append([tag(a) for a in A.A])
301
+
302
+ # Reset the ansatz to the initial condition
303
+ # print("ansatz before reset:",A.A)
304
+ set_ref(A, ref_init)
305
+ reset(A)
306
+ # print("tlist:",t_list)
307
+ # Return solution object
308
+ return AVQDSol(t_list, u_list, theta_list, A_list, jump_L_list, jump_t_list, status=0 if not break_flag else 1)
309
+
310
+ # Function to evolve a single trajectory and collect results
311
+ def solve_avq_trajectory(H, ansatz, tf, dt):
312
+ # Solve for a single trajectory using solve_avq
313
+ res = solve_avq_traj(H, ansatz, [0, tf], dt, save_state=True, save_everystep=True)
314
+
315
+ # Post-process the results to extract energy and populations
316
+ tlist = res.t
317
+ psi_list = res.u
318
+ energy = []
319
+ pop = []
320
+
321
+ for i in range(len(tlist)):
322
+ psi = psi_list[i]
323
+ energy.append(np.real(np.conj(psi.T) @ (H.He) @ psi)) # Energy
324
+ pop.append([np.abs(psi[0])**2, np.abs(psi[1])**2]) # Population in ground/excited states for amplitude damping
325
+
326
+ return Result(tlist, psi_list, energy, pop, res.θ, res.A, res.jump_t, res.jump_L, res.status)
327
+ pass
328
+
329
+ def solve_avq_vect(H, A, tspan, dt):
330
+ ref_init = A.ref.copy()
331
+ nqbit = A.nqbit
332
+ update_state(A)
333
+ t = tspan[0]
334
+ t_list = [t]
335
+ u_list = [A.state.reshape(2**nqbit, 2**nqbit)]
336
+ theta_list = [A.theta.copy()]
337
+ A_list = [[tag(a) for a in A.A]]
338
+ norm_list = [1.0]
339
+ Gamma = 0
340
+ while t + dt <= tspan[1]:
341
+ He = H.He
342
+ Ha = H.Ha
343
+ one_step(A, He, Ha, dt)
344
+ psi_ = A.state
345
+ Gamma += 2 * np.real(psi_.T.conj() @ Ha @ psi_) * dt
346
+ ρ = psi_.reshape(2**nqbit, 2**nqbit)
347
+ ρ /= np.trace(ρ)
348
+ t += dt
349
+ t_list.append(t)
350
+ u_list.append(ρ)
351
+ theta_list.append(A.theta.copy())
352
+ A_list.append([tag(a) for a in A.A])
353
+ norm_list.append(np.exp(-Gamma))
354
+ set_ref(A, ref_init)
355
+ reset(A)
356
+ return AVQDSol(t_list, u_list, theta_list, A_list, [], [], norm=norm_list)
@@ -0,0 +1,144 @@
1
+ Metadata-Version: 2.4
2
+ Name: qflux
3
+ Version: 0.0.1
4
+ Summary: qflux is a package for running quantum dynamics calculations on quantum devices.
5
+ Author-email: Brandon Allen <brandon.allen@yale.edu>, Delmar Cabral <delmar.azevedocabral@yale.edu>, Alexander Soudackov <alexander.soudackov@yale.edu>, Anton Morgunov <anton@ischemist.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/batistagroup/qflux
8
+ Project-URL: Issues, https://github.com/batistagroup/qflux/issues
9
+ Project-URL: Documentation, https://qflux.batistalab.com
10
+ Keywords: Quantum Computing,chemistry,quantum dynamics
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: requests
15
+ Requires-Dist: importlib-metadata
16
+ Requires-Dist: qiskit>=2.0.0
17
+ Requires-Dist: qiskit-aer>=0.17.0
18
+ Requires-Dist: qiskit-algorithms>=0.3.1
19
+ Requires-Dist: qiskit-ibm-runtime>=0.37.0
20
+ Requires-Dist: tomli>=2.2.1
21
+ Requires-Dist: matplotlib>=3.10
22
+ Requires-Dist: numpy>=2.0
23
+ Requires-Dist: pylatexenc>=2.10
24
+ Requires-Dist: qutip>=5.0
25
+ Requires-Dist: scipy
26
+ Requires-Dist: tqdm
27
+ Provides-Extra: dev
28
+ Requires-Dist: ipykernel>=6.29.5; extra == "dev"
29
+ Requires-Dist: rich>=13.9.4; extra == "dev"
30
+ Requires-Dist: pre-commit>=4.1.0; extra == "dev"
31
+ Requires-Dist: ruff>=0.9.6; extra == "dev"
32
+ Requires-Dist: pytest>=8.3.4; extra == "dev"
33
+ Requires-Dist: mypy>=1.15.0; extra == "dev"
34
+ Requires-Dist: mkdocs>=1.6.1; extra == "dev"
35
+ Requires-Dist: mkdocstrings-python>=1.15.0; extra == "dev"
36
+ Requires-Dist: material-plausible-plugin>=0.3.0; extra == "dev"
37
+ Requires-Dist: mkdocs-material>=9.6.4; extra == "dev"
38
+ Requires-Dist: types-tqdm>=4.67.0.20241221; extra == "dev"
39
+ Provides-Extra: gqme
40
+ Requires-Dist: mpsqd; extra == "gqme"
41
+ Dynamic: license-file
42
+
43
+ [![License: GNU AGPL v3](https://img.shields.io/badge/License-GNU_AGPL_v3-lightgrey.svg)](LICENCE)
44
+ [![Static Badge](https://img.shields.io/badge/CQDMQD-00268d?style=flat&logoColor=00268d&label=NSF&labelColor=00268d&color=00268d&link=https%3A%2F%2Fcqdmqd.yale.edu%2F)](https://cqdmqd.yale.edu/)
45
+
46
+
47
+ # QFlux - A Quantum Computer Dynamics Package
48
+
49
+ This repository contains various protocols for performing quantum dynamics simulations with quantum devices. Each submodule contains object implementations for these protocols as demonstrated in a publication, as well as comprehensive tutorial notebooks designed to help users understand, implement and build upon various simulation techniques for studying quantum dynamics using quantum computer frameworks. Each tutorial is provided in Python, using Jupyter Notebooks to offer detailed explanations in both markdown and code comments.
50
+
51
+
52
+ ## Table of Contents
53
+
54
+ 1. [Getting Started](#start)
55
+ - [Documentation](#docs)
56
+ - [Notebooks For Tutorial Manuscript](#notebooks)
57
+ - [Additional Repositories](#repos)
58
+ 2. [Contribution Guidelines](#contribute)
59
+ 3. [Citation](#citation)
60
+ 4. [License](#license)
61
+ 5. [Acknowledgements](#acknowledgement)
62
+
63
+
64
+ ## Getting Started <a name="start"></a>
65
+
66
+ Simply select a notebook and execute them locally or in google collab. Necessary dependencies will be installed using `pip`.
67
+
68
+ If using uv through the commandline, use the following syntax to create and activate a virtual environment:
69
+
70
+ ```bash
71
+ uv venv
72
+ source .venv/bin/activate
73
+ ```
74
+
75
+ The necessary packages, including development, can be installed as follows:
76
+
77
+ ```bash
78
+ uv pip install -e ".[dev]"
79
+ ```
80
+
81
+ ### Documentation <a name="docs"></a>
82
+
83
+ Documentation for QFlux, illustrating its features and representative examples, is available at the following page:
84
+
85
+ https://qflux.batistalab.com/
86
+
87
+ ### Notebooks For Tutorial Manuscript <a name="notebooks"></a>
88
+
89
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/batistagroup/qflux/blob/master/demos/tutorial/Part_I.ipynb) | Part I - Closed Quantum Dynamics and Simulation Protocols
90
+
91
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/batistagroup/qflux/blob/master/demos/tutorial/Part_I_appendixA.ipynb) | Part I - Appendix A: Variational Methods
92
+
93
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/batistagroup/qflux/blob/master/demos/tutorial/Part_I_appendixB.ipynb) | Part I - Appendix B: Bosonic Simulation
94
+
95
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/batistagroup/qflux/blob/master/demos/tutorial/Part_II.ipynb) | Part II - Open Quantum Dynamics
96
+
97
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/batistagroup/qflux/blob/master/demos/tutorial/Part_III_B.ipynb) | Part III - Variational Quantum Trajectory Dynamics for FMO
98
+
99
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/batistagroup/qflux/blob/master/demos/tutorial/Part_III_A.ipynb) | Part III - Variational Quantum Dynamics for Amplitude Damping
100
+
101
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/batistagroup/qflux/blob/master/demos/tutorial/Part_IV.ipynb) | Part IV - Generalized Quantum Master Equation Dynamics
102
+
103
+ ### Contribution Guidelines <a name="contribute"></a>
104
+
105
+ To contribute to the repository, clone the qflux repository and create a new branch:
106
+
107
+ ```bash
108
+ git clone git@github.com:batistagroup/qflux.git
109
+ git pull
110
+ git checkout -b part_II_docs_spinchain
111
+ ```
112
+
113
+ For example to contribute to the documentation, written in markdown (.md), edit the markdown in some form and make it complete (vim spin_chain.md for example).
114
+ Once complete, commit changes to file:
115
+
116
+ ```bash
117
+ git add spin_chain.md
118
+ git commit -m 'DOCS: Added docs on the spin chain example with Lindblad'
119
+ git push
120
+ ```
121
+
122
+ Generate a new pull request through github and assign to a tentative reviewer.
123
+
124
+ ### Additional Repositories <a name="repos"></a>
125
+
126
+ [![Static Badge](https://img.shields.io/badge/Open_in_Github-181717.svg?&logo=github&logoColor=white)](https://github.com/dcabral00/qc_spin_tutorial) | Spin Chain Tutorial Repository
127
+
128
+ [![Static Badge](https://img.shields.io/badge/Open_in_Github-181717.svg?&logo=github&logoColor=white)](https://github.com/saurabhshivpuje/QMAD) | QMultiAdapt Repository
129
+
130
+ [![Static Badge](https://img.shields.io/badge/Open_in_Github-181717.svg?&logo=github&logoColor=white)](https://github.com/XiaohanDan97/CCI_PartIII_GQME) | GQME Tutorial Repository
131
+
132
+
133
+ ## Citation <a name="citation"></a>
134
+
135
+ Please cite the preprint of our work when using this code until the journal version becomes available.
136
+
137
+
138
+ ## Licensing <a name="license"></a>
139
+
140
+ Each notebook or repository might have its own licensing. Please refer to the individual README files and notebooks within each directory for specific licensing information.
141
+
142
+ ## Acknowledgement <a name="acknowledgement"></a>
143
+
144
+ We acknowledge the financial support of the National Science Foundation under award number 2124511, CCI Phase I: NSF Center for Quantum Dynamics on Modular Quantum Devices (CQD-MQD).
@@ -0,0 +1,38 @@
1
+ qflux/__init__.py,sha256=j0hovUC2F2GdGooe2jExe89bXQh4HSozB26mOmOx03o,129
2
+ qflux/GQME/__init__.py,sha256=zeTbgWoan3pUfp5aa7MU-ywWBTHAOp4RpLNE4IXW6bU,115
3
+ qflux/GQME/dynamics_GQME.py,sha256=pFK75IqyTsLhODKSHnQiRMyQn8YDgyt-eFPiFAHjwUQ,16849
4
+ qflux/GQME/params.py,sha256=u7mHRdbbf88ccTIvw9Hb4AunlfNBrzara0OZTL80vwk,1822
5
+ qflux/GQME/readwrite.py,sha256=JUUEsDL8Ep705P8iwlQ4YjAm7MswQ-eNpH1wa8_P-_I,3583
6
+ qflux/GQME/tdvp.py,sha256=32Z_cLJornzM4D63nmqekhwtc-OosrQcZhIeEZAqq9s,7136
7
+ qflux/GQME/tt_tfd.py,sha256=-RPH9aiCinLzG0VdZo43UBVKWcuoplkFmi77oOtv5zU,15204
8
+ qflux/closed_systems/__init__.py,sha256=CBnnqCBp0MD7jCGq1P0nzwCyR3okp4jkC8tvqWUTBCY,472
9
+ qflux/closed_systems/classical_methods.py,sha256=Etqjd9OkqCgPzhC2-FgQWlIiTu66V2_7LRftPDwBrb8,15882
10
+ qflux/closed_systems/custom_execute.py,sha256=Mk24DEvEbQlnu52MqhnSOGBpplHoAMz5__AcBKo1E_4,656
11
+ qflux/closed_systems/hamiltonians.py,sha256=ArdljgB7ASUq5QIKdN8CRdhf7b_2nFyb8OPacOGGvEs,3156
12
+ qflux/closed_systems/qubit_methods.py,sha256=NPC0pLM8Jok4bpkTBcDvDNO3YqsCpw9S6MVMxRHwcuU,10882
13
+ qflux/closed_systems/spin_dynamics_oo.py,sha256=cn4aRM3wYkP6CBbL-LhlUMR4dqQSQK7bpSV-twSzFbU,13925
14
+ qflux/closed_systems/spin_propagators.py,sha256=pMg4ttThkXw2kzBlY2yDpdomTn-7alRtpKUAxD-vSl8,11496
15
+ qflux/closed_systems/utils.py,sha256=mv5zGM9WAM4NCOhD5SpzGNS3iuCNZTPVfV_pbGQUlMQ,6969
16
+ qflux/open_systems/__init__.py,sha256=pHbE5rHa0ktH9ZCWUECbmgXQxeS_dJ4PQ5GBhtM9uJk,102
17
+ qflux/open_systems/dilation_circuit.py,sha256=hzzIga8vE4HAyJT1WM0eOB4jA-e32g0dv7P70BfpazA,5908
18
+ qflux/open_systems/numerical_methods.py,sha256=Hv9CJwRa_Kdp8dP7nHt2JJfBx_5w1qMIj_Faaqs9IzM,11981
19
+ qflux/open_systems/params.py,sha256=VsMGDwPqmgxnyl1G_oufopZaNx2duiOQ3g-Bpjp3yJA,676
20
+ qflux/open_systems/quantum_simulation.py,sha256=rwAAr23mFouc0vg2L9QetfV4X1H5_F1eiMzfBUXdvsM,14969
21
+ qflux/open_systems/trans_basis.py,sha256=KG0BNDdW72CUcJ_Qffu8PjrMfJMCc9qhUwUloVX14Bw,4092
22
+ qflux/open_systems/walsh_gray_optimization.py,sha256=5IgHjknFYhWEslOzElicJvJUYwCWNZNqn3N1z-AQzMY,7682
23
+ qflux/typing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
+ qflux/typing/examples.py,sha256=Sj66GKPZas2ALTsy5Cq14ds26xOpsOQDhifAQ9tKVFw,853
25
+ qflux/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
+ qflux/utils/io.py,sha256=-d_nRKp2ePvLjOJNlRF9x8rs_2z6C5_jLBh-BuUFa80,480
27
+ qflux/utils/logging_config.py,sha256=xvrzBmXYGfd8NdNViT1ebyngXs8_UqRtkeY_4gQmV1w,2264
28
+ qflux/variational_methods/__init__.py,sha256=rQCX9vWIrWJg54Xt-dZ7r6lXt6oh16SmD3tBDVuChIA,17
29
+ qflux/variational_methods/qmad/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
+ qflux/variational_methods/qmad/ansatz.py,sha256=cWhXnE6KgOD7Shd9sXtZXhYhfjDan3pPhu3WKTDY-4o,1887
31
+ qflux/variational_methods/qmad/ansatzVect.py,sha256=KrqBVqoYYXcQWUGtRxVP10NCrl5gq0v_-uqGeHAkGFo,1852
32
+ qflux/variational_methods/qmad/effh.py,sha256=_T7MiDFGOYB9WA0KxEnaLKs-iIn4dZEKuUep71xh-h0,2640
33
+ qflux/variational_methods/qmad/solver.py,sha256=eYHlAYOY_QzA322v-fQgXPc5M-F_FSjSgupHs7mCupA,11669
34
+ qflux-0.0.1.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
35
+ qflux-0.0.1.dist-info/METADATA,sha256=ZPDxnoYwkFclZ3cM9kAIUH17tbsom4KN7uNjp93GpkU,7055
36
+ qflux-0.0.1.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
37
+ qflux-0.0.1.dist-info/top_level.txt,sha256=GZgw1Z1DZDPg78NCF1dXCHw_f4usRh5HP5yLtgECIpo,6
38
+ qflux-0.0.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.4.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+