Skip to content

Commit cf54d38

Browse files
committed
Adding Frank's spinchain example
1 parent 0355a8a commit cf54d38

File tree

1 file changed

+168
-0
lines changed

1 file changed

+168
-0
lines changed
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
# Quandary's python interface functions are defined in /path/to/quandary/quandary.py. Import them here.
2+
from quandary import *
3+
np.random.seed(9001)
4+
5+
### Define some case's coefficients
6+
def get_deterministic_params(N, h_amp, U_amp, J_amp):
7+
h = h_amp * np.ones(N)
8+
U = U_amp * np.ones(N-1)
9+
J = J_amp * np.ones(N-1)
10+
return h, U, J
11+
12+
def get_xx_params(N, J_amp):
13+
h = np.zeros(N)
14+
U = np.zeros(N-1)
15+
J = J_amp * np.ones(N-1)
16+
return h, U, J
17+
18+
def get_disordered_xx_params(N, h_amp, J_amp):
19+
h = np.random.uniform(-h_amp, h_amp, N)
20+
U = np.zeros(N)
21+
J = J_amp * np.ones(N)
22+
return h, U, J
23+
24+
def get_xxz_params(N, U_amp, J_amp):
25+
h = np.zeros(N)
26+
U = U_amp * np.ones(N)
27+
J = J_amp * np.ones(N)
28+
return h, U, J
29+
30+
def get_disordered_xxz_params(N, h_amp, U_amp, J_amp):
31+
h = np.random.uniform(-h_amp, h_amp, N)
32+
U = U_amp * np.ones(N)
33+
J = J_amp * np.ones(N)
34+
return h, U, J
35+
36+
def mapCoeffs_SpinChainToQuandary(N:int, h:list, U:list, J:list):
37+
"""
38+
Map spin chain coefficents J, U and h onto Quandary coefficients
39+
40+
Parameters:
41+
------------
42+
N : int : number of spin sites
43+
J : float : J-coefficient per linear chain coupling: J[i] couples i and i+1
44+
U : list(float) : U-coefficient per linear chain coupling: J[i] couples i and i+1
45+
h : list(float) : h-coefficient per spin site
46+
47+
Output:
48+
--------
49+
freq01 : 01-transition frequency per qubit (omega_j)
50+
crossker : crossker coupling (linear chain) (xi_ij)
51+
Jkl : dipole-dipole coupling (linear chain) (J_ij)
52+
"""
53+
54+
# 01 transition frequencies [GHz] per site (omega_q)
55+
freq01 = np.zeros(N)
56+
for i in range(1,N-1):
57+
freq01[i] = (-2*h[i] -2*U[i] -2*U[i-1]) / (2*np.pi)
58+
freq01[0] = (-2*h[0] - 2*U[0] ) / (2*np.pi)
59+
freq01[N-1] = (-2*h[N-1] - 2*U[N-2]) / (2*np.pi)
60+
# Jkl and Xi term [GHz] (Format [0<->1, 0<->2, ..., 1<->2, ... ])
61+
Jkl=[]
62+
crosskerr=[]
63+
couplingID = 0
64+
for i in range(N):
65+
for j in range(i+1, N):
66+
if j == i+1: # linear chain coupling
67+
valJ = - 2*J[couplingID] / (2*np.pi)
68+
valC = - 4*U[couplingID] / (2*np.pi)
69+
else:
70+
valJ = 0.0
71+
valC = 0.0
72+
Jkl.append(valJ)
73+
crosskerr.append(valC)
74+
couplingID += 1
75+
return freq01, crosskerr, Jkl
76+
#####
77+
78+
# Specify the number of spin sites
79+
N = 8
80+
81+
# Get spin chain case coefficients
82+
U_amp = 1.0
83+
J_amp = 1.0
84+
h_amp = 1.0
85+
h, U, J = get_disordered_xx_params(N, U_amp, J_amp)
86+
87+
# Specify the initial state (list of 0 or 1 per site). Here: domain wall |111...000>
88+
initstate= np.zeros(N, dtype=int)
89+
for i in range(int(N/2)):
90+
initstate[i] = 1
91+
92+
# Set the simulation duration and step size
93+
T = 10.0
94+
# T = 4.0
95+
dT = 0.01 # Double check if this is small enough (e.g. by re-running with smaller dT and compare results)
96+
97+
# Quandary run options
98+
verbose = True
99+
ncores=8 # Numbers of cores for Quandary
100+
mpirun = "mpirun -np " # MPI executable, e.g. "srun -n" for LC (note the space after '-np ' for mpirun vs no space after '-n' for srun)
101+
102+
# Prepare Quandary
103+
initcondstr = "pure, "
104+
for e in initstate:
105+
initcondstr += str(e) +", "
106+
freq01, crosskerr, Jkl = mapCoeffs_SpinChainToQuandary(N, h, U, J)
107+
quandary = Quandary(Ne=[2 for _ in range(N)], Ng=[0 for _ in range(N)], freq01=freq01, rotfreq=np.zeros(N), crosskerr=crosskerr, Jkl=Jkl, initialcondition=initcondstr, T=T, dT=dT, initctrl_MHz=0.0, carrier_frequency=[[0.0] for _ in range(N)], verbose=verbose)
108+
109+
# Storage for averaged magnetization. Matrix rows = sites, cols = time
110+
magnet = np.zeros((N,quandary.nsteps+1))
111+
# Storage for averaged domain wall spread
112+
nhalf = np.zeros(quandary.nsteps+1)
113+
114+
# Number of samples for h
115+
# nsamples = 10
116+
nsamples = 1
117+
118+
# Iterate over randomized h and run quandary
119+
for isample in range(nsamples):
120+
121+
# Sample new set of coefficients and map to Quandary's coeffs
122+
h, U, J = get_disordered_xx_params(N, U_amp, J_amp)
123+
quandary.freq01, quandary.crosskerr, quandary.Jkl = mapCoeffs_SpinChainToQuandary(N, h, U, J)
124+
quandary.update()
125+
126+
# Run forward simulation
127+
datadir = "./N"+str(N)+"_sample" + str(isample)+"_run_dir_parallel"
128+
t, pt, qt, infidelity, expectedEnergy, population = quandary.simulate(datadir=datadir, maxcores=ncores, mpirun=mpirun)
129+
130+
# Compute magnetization from expected Energy (-2*expEnergy + 1) and add to average
131+
for isite in range(N):
132+
for nt in range(len(t)):
133+
exp = expectedEnergy[isite][0][nt] ## expected energy for this site and time
134+
magnet_this = -2.0*exp + 1.0
135+
magnet[isite,nt] += magnet_this / nsamples
136+
137+
# Compute domain wall spread (N_1/2) from expected Energy and add to average
138+
for nt in range(len(t)): # iterate over time
139+
nhalf_i = 0.0
140+
for isite in range(int(N/2)): # iterate over first half of the sites
141+
nhalf_i -= expectedEnergy[isite][0][nt]
142+
nhalf_i += int(N/2)
143+
nhalf[nt] += nhalf_i / nsamples
144+
145+
# # Plot sigmaz dynamics of one spin site
146+
# isite = 0
147+
# myexp = [-2*e+1 for e in expectedEnergy[isite][0]]
148+
# plt.plot(t, myexp)
149+
# plt.show()
150+
151+
# Plot heatmap of magnetization
152+
fig, ax = plt.subplots(figsize=(6,4))
153+
mycmap = plt.get_cmap('coolwarm')
154+
plt.imshow(magnet, interpolation='none', aspect='auto', cmap=mycmap)
155+
plt.colorbar()
156+
plt.title(r"Heat Map of Spin Chain $\langle \sigma^z_j \rangle$")
157+
plt.xlabel("Time-step index")
158+
plt.ylabel("Spin Site Index $j$")
159+
plt.show()
160+
161+
# Plot domain wall spread:
162+
plt.plot(t, nhalf)
163+
plt.xlabel("Time-step index")
164+
plt.ylabel("N_1/2")
165+
plt.grid(True)
166+
plt.legend()
167+
plt.show()
168+

0 commit comments

Comments
 (0)