Skip to content

Commit 9a46f16

Browse files
Optimize tfim_validation.py
1 parent 83d6df5 commit 9a46f16

File tree

1 file changed

+21
-64
lines changed

1 file changed

+21
-64
lines changed

scripts/tfim_validation.py

Lines changed: 21 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from qiskit.quantum_info import Statevector
1818
from 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

Comments
 (0)