1717from qiskit .quantum_info import Statevector
1818from qiskit .transpiler import CouplingMap
1919
20- from pyqrackising import generate_tfim_samples
20+ from pyqrackising import generate_tfim_samples , get_tfim_hamming_distribution
2121
2222
2323# Factor the qubit width for torus dimensions that are close as possible to square
@@ -270,10 +270,6 @@ def main():
270270 for q in range (n_qubits ):
271271 qc_aer .ry (theta , q )
272272
273- qrack_probs = dict (Counter (generate_tfim_samples (J = J , h = h , z = z , theta = theta , t = 0 , n_qubits = n_qubits , shots = shots )))
274- for key in qrack_probs .keys ():
275- qrack_probs [key ] /= shots
276-
277273 control = AerSimulator (method = "statevector" )
278274 qc_aer = transpile (
279275 qc_aer ,
@@ -285,22 +281,19 @@ def main():
285281 control_probs = Statevector (job .result ().get_statevector ()).probabilities ()
286282
287283 n_bias = n_qubits + 1
288- bias_0 = np .zeros (n_bias , dtype = float )
289- magnetization_0 , sqr_magnetization_0 = 0 , 0
284+ bias_0 = get_tfim_hamming_distribution (J = J , h = h , z = z , theta = theta , t = 0 , n_qubits = n_qubits )
285+ qrack_probs = dict (Counter (generate_tfim_samples (J = J , h = h , z = z , theta = theta , t = 0 , n_qubits = n_qubits , shots = shots )))
286+ for key in qrack_probs .keys ():
287+ qrack_probs [key ] /= shots
288+
289+ sqr_magnetization_0 = 0
290290 for key , value in qrack_probs .items ():
291291 m = 0
292- h = 0
293292 for _ in range (n_qubits ):
294- if key & 1 :
295- h += 1
296- m -= 1
297- else :
298- m += 1
293+ m += - 1 if key & 1 else 1
299294 key >>= 1
300295 m /= n_qubits
301- magnetization_0 += value * m
302296 sqr_magnetization_0 += value * m * m
303- bias_0 [h ] += value
304297
305298 c_magnetization , c_sqr_magnetization = 0 , 0
306299 for p in range (1 << n_qubits ):
@@ -351,65 +344,29 @@ def main():
351344 t = d * dt
352345 # Determine how to weight closed-form vs. conventional simulation contributions:
353346 model = (1 - math .exp (- t / t1 )) if (t1 > 0 ) else 1
354- d_magnetization = 0
355- d_sqr_magnetization = 0
356347
357348 # "p" is the exponent of the geometric series weighting, for (n+1) dimensions of Hamming weight.
358349 # Notice that the expected symmetries are respected under reversal of signs of J and/or h.
359350 zJ = z * J
360351 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 )))
361352
362353 # The magnetization components are weighted by (n+1) symmetric "bias" terms over possible Hamming weights.
363- bias = np .zeros (n_bias , dtype = np .float64 )
364- if h <= sys .float_info .epsilon :
365- # This agrees with small perturbations away from h = 0.
366- d_magnetization = 1
367- d_sqr_magnetization = 1
368- bias [0 ] = 1.0
369- else :
370- p = (
371- 2.0 ** (abs (J / h ) - 1.0 )
372- * (1.0 + math .sin (theta - theta_c ) * math .cos (omega * J * t + theta ) / (1.0 + math .sqrt (t )))
373- - 0.5
374- )
375-
376- factor = 2.0 ** - (p / n_bias )
377- if factor <= sys .float_info .epsilon :
378- d_magnetization = 1
379- d_sqr_magnetization = 1
380- bias [0 ] = 1.0
381- else :
382- result = 1.0
383- tot_n = 0
384- for q in range (n_bias ):
385- result *= factor
386- m = (n_qubits - (q << 1 )) / n_qubits
387- d_magnetization += result * m
388- bias [q ] = result
389- tot_n += result
390- # Normalize the results for 1.0 total marginal probability.
391- d_magnetization /= tot_n
392- bias /= tot_n
393-
394- qrack_probs = dict (Counter (generate_tfim_samples (J = J , h = h , z = z , theta = theta , t = t , n_qubits = n_qubits , shots = shots )))
395- for key in qrack_probs .keys ():
396- qrack_probs [key ] /= shots
397- for key , value in qrack_probs .items ():
398- m = 0
399- for _ in range (n_qubits ):
400- m += - 1 if key & 1 else 1
401- key >>= 1
402- m /= n_qubits
403- d_sqr_magnetization += value * m * m
404-
405- if J > 0 :
406- # This is antiferromagnetism.
407- bias = bias [::- 1 ]
408- d_magnetization = - d_magnetization
354+ bias = get_tfim_hamming_distribution (J = J , h = h , z = z , theta = theta , t = t , n_qubits = n_qubits )
355+ qrack_probs = dict (Counter (generate_tfim_samples (J = J , h = h , z = z , theta = theta , t = t , n_qubits = n_qubits , shots = shots )))
356+ for key in qrack_probs .keys ():
357+ qrack_probs [key ] /= shots
358+
359+ d_sqr_magnetization = 0
360+ for key , value in qrack_probs .items ():
361+ m = 0
362+ for _ in range (n_qubits ):
363+ m += - 1 if key & 1 else 1
364+ key >>= 1
365+ m /= n_qubits
366+ d_sqr_magnetization += value * m * m
409367
410368 # Mix in the initial state component.
411369 bias = model * bias + (1 - model ) * bias_0
412- magnetization = model * d_magnetization + (1 - model ) * magnetization_0
413370 sqr_magnetization = model * d_sqr_magnetization + (1 - model ) * sqr_magnetization_0
414371
415372 # The full 2^n marginal probabilities will be produced in the statistics calculation,
0 commit comments