Skip to content

Commit 8339b25

Browse files
committed
Create testtrotter.py
1 parent 87a4d08 commit 8339b25

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import numpy as np
2+
from scipy.linalg import expm
3+
4+
# --- Simulation Parameters (user configurable) ---
5+
num_qubits = 3 # Number of qubits in the system
6+
num_terms = 3 * num_qubits # Number of random Pauli terms in H (e.g., 3*n)
7+
total_time = 1.0 # Total evolution time
8+
trotter_steps = 10 # Number of Trotter steps (N)
9+
track_error = False # If True, track fidelity at each step (prints overlaps)
10+
11+
np.random.seed(42) # Set a random seed for reproducibility (optional)
12+
13+
# Define Pauli matrices (2x2 complex NumPy arrays)
14+
I = np.eye(2, dtype=complex)
15+
X = np.array([[0, 1], [1, 0]], dtype=complex)
16+
Y = np.array([[0, -1j], [1j, 0]], dtype=complex)
17+
Z = np.array([[1, 0], [0, -1]], dtype=complex)
18+
paulis = [I, X, Y, Z]
19+
pauli_labels = ['I', 'X', 'Y', 'Z'] # for reference/printing
20+
21+
# Randomly generate a Hamiltonian as a sum of Pauli strings
22+
terms = [] # list to hold (coeff, matrix, label) for each term
23+
dim = 2 ** num_qubits
24+
H = np.zeros((dim, dim), dtype=complex) # Hamiltonian matrix
25+
for term_index in range(num_terms):
26+
# Randomly pick a Pauli for each qubit to form a tensor-product term
27+
matrices = []
28+
labels = []
29+
for q in range(num_qubits):
30+
choice = np.random.randint(0, 4) # 0=I, 1=X, 2=Y, 3=Z
31+
matrices.append(paulis[choice])
32+
labels.append(pauli_labels[choice])
33+
# Ensure the term is not Identity on all qubits (if so, replace one factor with X)
34+
if all(lbl == 'I' for lbl in labels):
35+
rand_q = np.random.randint(0, num_qubits)
36+
matrices[rand_q] = X
37+
labels[rand_q] = 'X'
38+
# Construct the term matrix via Kronecker (tensor) product
39+
term_matrix = matrices[0]
40+
for mat in matrices[1:]:
41+
term_matrix = np.kron(term_matrix, mat)
42+
# Random real coefficient for this term
43+
coeff = np.random.uniform(-1.0, 1.0)
44+
# Add to Hamiltonian
45+
H += coeff * term_matrix
46+
terms.append((coeff, term_matrix, "".join(labels)))
47+
48+
# Print out the generated Hamiltonian terms (for information)
49+
print(f"Hamiltonian has {len(terms)} terms on {num_qubits} qubits:")
50+
for coeff, _, label in terms:
51+
print(f" {coeff:+.3f} * ({label})")
52+
53+
# Initial state |00...0>: a vector of size 2^n with 1 in the 0th element
54+
initial_state = np.zeros(dim, dtype=complex)
55+
initial_state[0] = 1.0
56+
57+
# Prepare for Trotter evolution
58+
dt = total_time / trotter_steps # time step size
59+
state = initial_state.copy() # will hold the evolving state vector
60+
61+
# (Optional) prepare for exact intermediate evolution tracking
62+
if track_error:
63+
U_step = expm(-1j * H * dt) # exact propagator for one step
64+
exact_state = initial_state.copy() # will hold exact state as we step through
65+
66+
# --- Main Trotter Evolution Loop ---
67+
for step in range(trotter_steps):
68+
# Apply each term's evolution for this time slice
69+
for (coeff, term_matrix, label) in terms:
70+
theta = coeff * dt # the angle for this term's evolution
71+
# Using exp(-i * coeff * P * dt) = I * cos(theta) - i * P * sin(theta)
72+
cos_theta = np.cos(theta)
73+
sin_theta = np.sin(theta)
74+
# Update state: new_state = cos(theta)*state - i * sin(theta) * (P * state)
75+
state = cos_theta * state - 1j * sin_theta * (term_matrix.dot(state))
76+
# After applying all terms, one full Trotter step is complete.
77+
if track_error:
78+
# Update exact state by one full step and compute fidelity
79+
exact_state = U_step.dot(exact_state)
80+
overlap = np.vdot(exact_state, state) # inner product <psi_exact | psi_trotter>
81+
fidelity = np.abs(overlap)**2
82+
print(f"Step {step+1:2d}/{trotter_steps}: fidelity = {fidelity:.6f}")
83+
84+
# Compute exact final state for comparison using full matrix exponential
85+
psi_exact_final = expm(-1j * H * total_time).dot(initial_state)
86+
87+
# Compute overlap and fidelity between Trotter result and exact result
88+
final_overlap = np.vdot(psi_exact_final, state)
89+
final_fidelity = np.abs(final_overlap)**2
90+
91+
print("\nFinal state (Trotter approximation):")
92+
print(state)
93+
print("\nFinal state (Exact evolution):")
94+
print(psi_exact_final)
95+
print(f"\nOverlap = {final_overlap:.6f}")
96+
print(f"Fidelity = {final_fidelity:.6f}")

0 commit comments

Comments
 (0)