@@ -94,6 +94,8 @@ def calc_stats(n_rows, n_cols, ideal_probs, bias, depth):
9494 diff_sqr = 0
9595 z_fidelity = 0
9696 sum_hog_counts = 0
97+ magnetization = 0
98+ sqr_magnetization = 0
9799 # total = 0
98100 # hamming_bias = [0.0] * (n + 1)
99101 for i in range (n_pow ):
@@ -112,6 +114,10 @@ def calc_stats(n_rows, n_cols, ideal_probs, bias, depth):
112114 # You can make sure this still adds up to 1.0, to show the distribution is normalized:
113115 # total += count
114116
117+ mag = 1.0 - 2 * hamming_weight / n
118+ magnetization += count * mag
119+ sqr_magnetization += count * mag * mag
120+
115121 # QV / HOG
116122 if ideal > threshold :
117123 sum_hog_counts += count
@@ -140,6 +146,8 @@ def calc_stats(n_rows, n_cols, ideal_probs, bias, depth):
140146 "z_fidelity" : float (z_fidelity ),
141147 "hog_prob" : sum_hog_counts ,
142148 "xeb" : xeb ,
149+ "magnetization" : magnetization ,
150+ "sqr_magnetization" : sqr_magnetization
143151 }
144152
145153
@@ -218,8 +226,6 @@ def main():
218226 n_qubits = 8
219227 depth = 20
220228 t1 = 0
221- t2 = 1
222- omega = 1.5
223229
224230 # Quantinuum settings
225231 J , h , dt , z = - 1.0 , 2.0 , 0.25 , 4
@@ -255,10 +261,7 @@ def main():
255261 trials = 8 if t1 > 0 else 1
256262
257263 print ("t1: " + str (t1 ))
258- print ("t2: " + str (t2 ))
259- print ("omega / pi: " + str (omega ))
260264
261- omega *= math .pi
262265 n_rows , n_cols = factor_width (n_qubits , False )
263266 qubits = list (range (n_qubits ))
264267
@@ -276,20 +279,7 @@ def main():
276279 control .run_qiskit_circuit (qc_aer )
277280 control_probs = control .out_probs ()
278281
279- n_bias = n_qubits + 1
280282 bias_0 = get_tfim_hamming_distribution (J = J , h = h , z = z , theta = theta , t = 0 , n_qubits = n_qubits )
281- qrack_probs = dict (Counter (generate_tfim_samples (J = J , h = h , z = z , theta = theta , t = 0 , n_qubits = n_qubits , shots = shots )))
282- for key in qrack_probs .keys ():
283- qrack_probs [key ] /= shots
284-
285- sqr_magnetization_0 = 0
286- for key , value in qrack_probs .items ():
287- m = 0
288- for _ in range (n_qubits ):
289- m += - 1 if key & 1 else 1
290- key >>= 1
291- m /= n_qubits
292- sqr_magnetization_0 += value * m * m
293283
294284 c_sqr_magnetization = 0
295285 for p in range (1 << n_qubits ):
@@ -301,10 +291,6 @@ def main():
301291 m /= n_qubits
302292 c_sqr_magnetization += control_probs [p ] * m * m
303293
304- # Save the sum of squares and sum of square residuals on the magnetization curve values.
305- ss = c_sqr_magnetization ** 2
306- ssr = (c_sqr_magnetization - sqr_magnetization_0 ) ** 2
307-
308294 result = calc_stats (
309295 n_rows ,
310296 n_cols ,
@@ -315,6 +301,11 @@ def main():
315301
316302 # Add up the square residuals:
317303 r_squared = result ["l2_difference" ] ** 2
304+ sqr_magnetization_0 = result ["sqr_magnetization" ]
305+
306+ # Save the sum of squares and sum of square residuals on the magnetization curve values.
307+ ss = c_sqr_magnetization ** 2
308+ ssr = (c_sqr_magnetization - sqr_magnetization_0 ) ** 2
318309
319310 qc_aer = QuantumCircuit (n_qubits )
320311 trotter_step (qc_aer , qubits , (n_rows , n_cols ), J , h , dt )
@@ -325,44 +316,15 @@ def main():
325316 basis_gates = basis_gates
326317 )
327318
328- r_squared = 0
329- ss = 0
330- ssr = 0
331319 for d in range (1 , depth + 1 ):
320+ t = d * dt
321+
332322 # For each depth step, we append an additional Trotter step to Aer's circuit.
333323 control .run_qiskit_circuit (qc_aer )
334324 control_probs = control .out_probs ()
335325
336- # This section calculates the geometric series weight per Hamming weight, with oscillating time dependence.
337- # The mean-field ground state is encapsulated as a multiplier on the geometric series exponent.
338- # Additionally, this same mean-field exponent is the amplitude of time-dependent oscillation (also in the geometric series exponent).
339- t = d * dt
340- # Determine how to weight closed-form vs. conventional simulation contributions:
341- model = (1 - math .exp (- t / t1 )) if (t1 > 0 ) else 1
342-
343- # "p" is the exponent of the geometric series weighting, for (n+1) dimensions of Hamming weight.
344- # Notice that the expected symmetries are respected under reversal of signs of J and/or h.
345- zJ = z * J
346- theta_c = ((np .pi if J > 0 else - np .pi ) / 2 ) if abs (zJ ) <= sys .float_info .epsilon else np .arcsin (max (- 1.0 , min (1.0 , h / zJ )))
347-
348326 # The magnetization components are weighted by (n+1) symmetric "bias" terms over possible Hamming weights.
349327 bias = get_tfim_hamming_distribution (J = J , h = h , z = z , theta = theta , t = t , n_qubits = n_qubits )
350- qrack_probs = dict (Counter (generate_tfim_samples (J = J , h = h , z = z , theta = theta , t = t , n_qubits = n_qubits , shots = shots )))
351- for key in qrack_probs .keys ():
352- qrack_probs [key ] /= shots
353-
354- d_sqr_magnetization = 0
355- for key , value in qrack_probs .items ():
356- m = 0
357- for _ in range (n_qubits ):
358- m += - 1 if key & 1 else 1
359- key >>= 1
360- m /= n_qubits
361- d_sqr_magnetization += value * m * m
362-
363- # Mix in the initial state component.
364- bias = model * bias + (1 - model ) * bias_0
365- sqr_magnetization = model * d_sqr_magnetization + (1 - model ) * sqr_magnetization_0
366328
367329 # The full 2^n marginal probabilities will be produced in the statistics calculation,
368330 # but notice that the global magnetization value only requires (n+1) dimensions of marginal probability,
@@ -378,6 +340,7 @@ def main():
378340
379341 # Add up the square residuals:
380342 r_squared += result ["l2_difference" ] ** 2
343+ sqr_magnetization = result ["sqr_magnetization" ]
381344
382345 # Calculate the "control-case" magnetization values, from Aer's samples.
383346 c_magnetization , c_sqr_magnetization = 0 , 0
0 commit comments