@@ -176,7 +176,7 @@ def sample_fixed_hamming_weight(h_weight, count, n_rows, n_cols, burnin=10):
176176 return samples
177177
178178
179- @njit
179+ @njit ( cache = True )
180180def factor_width (width , is_transpose = False ):
181181 col_len = math .floor (math .sqrt (width ))
182182 while ((width // col_len ) * col_len ) != width :
@@ -186,7 +186,7 @@ def factor_width(width, is_transpose=False):
186186 return (col_len , row_len ) if is_transpose else (row_len , col_len )
187187
188188
189- @njit
189+ @njit ( cache = True )
190190def comb (n , k ):
191191 if (k < 0 ) or (k > n ):
192192 return 0
@@ -198,7 +198,7 @@ def comb(n, k):
198198 return res
199199
200200
201- @njit
201+ @njit ( cache = True )
202202def fix_cdf (hamming_prob ):
203203 tot_prob = 0.0
204204 n_bias = len (hamming_prob )
@@ -211,55 +211,7 @@ def fix_cdf(hamming_prob):
211211 return cum_prob
212212
213213
214- @njit
215- def _apply_time_envelope (bias , t , n_qubits ):
216- """
217- Multiply bias[k] by exp(-|k - n/2| / max(t, epsilon)) for each k.
218-
219- This is the time-dependent Hamming weight envelope:
220- - At small t: peaks sharply at half-filling k = n/2 (AFM sector).
221- - At large t: envelope -> 1, recovering the original bias exactly.
222-
223- The differential effect is greatest at initialization (small t),
224- which is where the ESD / adiabatic physics lives.
225-
226- alpha = 1.0 is hardcoded as the natural physical invariant.
227- It is the least contrived value that produces the correct qualitative
228- behaviour, and is left fixed rather than tuned empirically.
229-
230- Authors: Claude (Anthropic) and D. Strano
231- """
232- alpha = 1.0
233- half = n_qubits / 2.0
234- # Numba-safe floor of t for the epsilon guard
235- t_eff = t if t > 1e-9 else 1e-9
236-
237- out = np .empty (n_qubits + 1 , dtype = np .float64 )
238- tot = 0.0
239- for k in range (n_qubits + 1 ):
240- dist = k - half
241- if dist < 0.0 :
242- dist = - dist
243- envelope = math .exp (- alpha * dist / t_eff )
244- val = bias [k ] * envelope
245- out [k ] = val
246- tot += val
247-
248- if tot <= 0.0 :
249- # Pathological underflow: collapse to half-filling delta
250- for k in range (n_qubits + 1 ):
251- out [k ] = 0.0
252- mid = n_qubits // 2
253- out [mid ] = 1.0
254- return out
255-
256- for k in range (n_qubits + 1 ):
257- out [k ] /= tot
258-
259- return out
260-
261-
262- @njit
214+ @njit (cache = True )
263215def get_tfim_hamming_distribution (J = - 1.0 , h = 2.0 , z = 4 , theta = 0.174532925199432957 , t = 5 , n_qubits = 56 , omega = 1.5 * np .pi ):
264216 if abs (t ) <= epsilon :
265217 p = (1.0 - np .cos (theta )) / 2.0
@@ -277,11 +229,7 @@ def get_tfim_hamming_distribution(J=-1.0, h=2.0, z=4, theta=0.174532925199432957
277229 bias [0 ] = 1.0
278230 return bias
279231
280- bias = probability_by_hamming_weight (J , h , z , theta , t , n_qubits + 1 , normalized = True , omega = omega )
281-
282- # Apply time-dependent envelope: maximum differential at small t,
283- # recovers original distribution as t -> inf.
284- return _apply_time_envelope (bias / bias .sum (), t , n_qubits )
232+ return probability_by_hamming_weight (J , h , z , theta , t , n_qubits + 1 , normalized = True , omega = omega )
285233
286234
287235def generate_tfim_samples (J = - 1.0 , h = 2.0 , z = 4 , theta = 0.174532925199432957 , t = 5 , n_qubits = 56 , shots = 100 ):
0 commit comments