pyqrack-cpu-complex128 1.58.0__py3-none-macosx_13_0_x86_64.whl → 1.58.10__py3-none-macosx_13_0_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pyqrack-cpu-complex128 might be problematic. Click here for more details.

@@ -102,6 +102,45 @@ class LHVQubit:
102
102
  self.ry(theta)
103
103
  self.rz(phi)
104
104
 
105
+ # Provided verbatim by Elara (the custom OpenAI GPT):
106
+ def mtrx(self, matrix):
107
+ """
108
+ Apply a 2x2 unitary matrix to the LHV Bloch vector using only standard math/cmath.
109
+ Matrix format: [a, b, c, d] for [[a, b], [c, d]]
110
+ """
111
+ a, b, c, d = matrix
112
+
113
+ # Current Bloch vector
114
+ x, y, z = self.bloch
115
+
116
+ # Convert to density matrix ρ = ½ (I + xσx + yσy + zσz)
117
+ rho = [[(1 + z) / 2, (x - 1j * y) / 2], [(x + 1j * y) / 2, (1 - z) / 2]]
118
+
119
+ # Compute U * ρ
120
+ u_rho = [
121
+ [a * rho[0][0] + b * rho[1][0], a * rho[0][1] + b * rho[1][1]],
122
+ [c * rho[0][0] + d * rho[1][0], c * rho[0][1] + d * rho[1][1]],
123
+ ]
124
+
125
+ # Compute (U * ρ) * U†
126
+ rho_prime = [
127
+ [
128
+ u_rho[0][0] * a.conjugate() + u_rho[0][1] * b.conjugate(),
129
+ u_rho[0][0] * c.conjugate() + u_rho[0][1] * d.conjugate(),
130
+ ],
131
+ [
132
+ u_rho[1][0] * a.conjugate() + u_rho[1][1] * b.conjugate(),
133
+ u_rho[1][0] * c.conjugate() + u_rho[1][1] * d.conjugate(),
134
+ ],
135
+ ]
136
+
137
+ # Extract Bloch components: Tr(ρ'σi) = 2 * Re[...]
138
+ new_x = 2 * rho_prime[0][1].real + 2 * rho_prime[1][0].real
139
+ new_y = 2 * (rho_prime[0][1].imag - rho_prime[1][0].imag)
140
+ new_z = 2 * rho_prime[0][0].real - 1 # since Tr(ρ') = 1
141
+
142
+ self.bloch = [new_x, new_y, new_z]
143
+
105
144
  def prob(self, basis=Pauli.PauliZ):
106
145
  """Sample a classical outcome from the current 'quantum' state"""
107
146
  if basis == Pauli.PauliZ:
@@ -404,7 +443,91 @@ class QrackAceBackend:
404
443
 
405
444
  return qb, lhv
406
445
 
407
- def _correct(self, lq, phase=False):
446
+ def _get_lhv_bloch_angles(self, sim):
447
+ # Z axis
448
+ z = 1 - 2 * sim.prob(Pauli.PauliZ)
449
+ prob = z**2
450
+
451
+ # X axis
452
+ x = 1 - 2 * sim.prob(Pauli.PauliX)
453
+ prob += x**2
454
+
455
+ # Y axis
456
+ y = 1 - 2 * sim.prob(Pauli.PauliY)
457
+ prob += y**2
458
+
459
+ prob = math.sqrt(prob)
460
+ inclination = math.atan2(math.sqrt(x**2 + y**2), z)
461
+ azimuth = math.atan2(y, x)
462
+
463
+ return prob, azimuth, inclination
464
+
465
+ def _get_bloch_angles(self, hq):
466
+ sim = self.sim[hq[0]]
467
+ q = hq[1]
468
+
469
+ # Z axis
470
+ z = 1 - 2 * sim.prob(q)
471
+ prob = z**2
472
+
473
+ # X axis
474
+ sim.h(q)
475
+ x = 1 - 2 * sim.prob(q)
476
+ prob += x**2
477
+ sim.h(q)
478
+
479
+ # Y axis
480
+ sim.adjs(q)
481
+ sim.h(q)
482
+ y = 1 - 2 * sim.prob(q)
483
+ prob += y**2
484
+ sim.h(q)
485
+ sim.s(q)
486
+
487
+ prob = math.sqrt(prob)
488
+ inclination = math.atan2(math.sqrt(x**2 + y**2), z)
489
+ azimuth = math.atan2(y, x)
490
+
491
+ return prob, azimuth, inclination
492
+
493
+ def _rotate_to_bloch(
494
+ self, hq, delta_azimuth, delta_inclination
495
+ ):
496
+ sim = self.sim[hq[0]]
497
+ q = hq[1]
498
+
499
+ # Apply rotation as "Azimuth, Inclination" (AI)
500
+ cosA = math.cos(delta_azimuth)
501
+ sinA = math.sin(delta_azimuth)
502
+ cosI = math.cos(delta_inclination / 2)
503
+ sinI = math.sin(delta_inclination / 2)
504
+
505
+ m00 = complex(cosI, 0)
506
+ m01 = complex(-cosA, sinA) * sinI
507
+ m10 = complex(cosA, sinA) * sinI
508
+ m11 = complex(cosI, 0)
509
+
510
+ sim.mtrx([m00, m01, m10, m11], q)
511
+
512
+
513
+ def _rotate_lhv_to_bloch(
514
+ self, sim, delta_azimuth, delta_inclination
515
+ ):
516
+ # Apply rotation as "Azimuth, Inclination" (AI)
517
+ cosA = math.cos(delta_azimuth)
518
+ sinA = math.sin(delta_azimuth)
519
+ cosI = math.cos(delta_inclination / 2)
520
+ sinI = math.sin(delta_inclination / 2)
521
+
522
+ m00 = complex(cosI, 0)
523
+ m01 = complex(-cosA, sinA) * sinI
524
+ m10 = complex(cosA, sinA) * sinI
525
+ m11 = complex(cosI, 0)
526
+
527
+ sim.mtrx([m00, m01, m10, m11])
528
+
529
+
530
+ def _correct(self, lq, phase=False, skip_rotation=False):
408
531
  hq = self._unpack(lq)
409
532
 
410
533
  if len(hq) == 1:
@@ -454,6 +577,34 @@ class QrackAceBackend:
454
577
  hq[q].x()
455
578
  else:
456
579
  self.sim[hq[q][0]].x(hq[q][1])
580
+
581
+ if not skip_rotation:
582
+ p, a, i = [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]
583
+ p[0], a[0], i[0] = self._get_bloch_angles(hq[0])
584
+ p[1], a[1], i[1] = self._get_bloch_angles(hq[1])
585
+ p[3], a[3], i[3] = self._get_bloch_angles(hq[3])
586
+ p[4], a[4], i[4] = self._get_bloch_angles(hq[4])
587
+
588
+ indices = []
589
+ a_target = 0
590
+ i_target = 0
591
+ weight = 0
592
+ for x in range(5):
593
+ if p[x] < 0.5:
594
+ continue
595
+ indices.append(x)
596
+ w = (1.5 - p[x])
597
+ w *= w
598
+ a_target += w * a[x]
599
+ i_target += w * i[x]
600
+ weight += w
601
+
602
+ if len(indices) > 1:
603
+ a_target /= weight
604
+ i_target /= weight
605
+ for x in indices:
606
+ self._rotate_to_bloch(hq[x], a_target - a[x], i_target - i[x])
607
+
457
608
  else:
458
609
  # RMS
459
610
  p = [
@@ -473,6 +624,31 @@ class QrackAceBackend:
473
624
  else:
474
625
  self.sim[hq[q][0]].x(hq[q][1])
475
626
 
627
+ if not skip_rotation:
628
+ p, a, i = [0, 0, 0], [0, 0, 0], [0, 0, 0]
629
+ p[0], a[0], i[0] = self._get_bloch_angles(hq[0])
630
+ p[1], a[1], i[1] = self._get_bloch_angles(hq[1])
631
+
632
+ indices = []
633
+ a_target = 0
634
+ i_target = 0
635
+ weight = 0
636
+ for x in range(3):
637
+ if p[x] < 0.5:
638
+ continue
639
+ indices.append(x)
640
+ w = (1.5 - p[x])
641
+ w *= w
642
+ a_target += w * a[x]
643
+ i_target += w * i[x]
644
+ weight += w
645
+
646
+ if len(indices) > 1:
647
+ a_target /= weight
648
+ i_target /= weight
649
+ for x in indices:
650
+ self._rotate_to_bloch(hq[x], a_target - a[x], i_target - i[x])
651
+
476
652
  if phase:
477
653
  for q in qb:
478
654
  b = hq[q]
@@ -496,8 +672,8 @@ class QrackAceBackend:
496
672
  b = hq[lhv]
497
673
  b.u(th, ph, lm)
498
674
 
499
- self._correct(lq, False)
500
- self._correct(lq, True)
675
+ self._correct(lq, False, True)
676
+ self._correct(lq, True, False)
501
677
 
502
678
  def r(self, p, th, lq):
503
679
  hq = self._unpack(lq)
@@ -521,7 +697,7 @@ class QrackAceBackend:
521
697
  b.rz(th)
522
698
 
523
699
  if p != Pauli.PauliZ:
524
- self._correct(lq, False)
700
+ self._correct(lq, False, p != Pauli.PauliX)
525
701
  if p != Pauli.PauliX:
526
702
  self._correct(lq, True)
527
703
 
@@ -745,7 +921,7 @@ class QrackAceBackend:
745
921
 
746
922
  self._correct(lq1, True)
747
923
  if pauli != Pauli.PauliZ:
748
- self._correct(lq2, False)
924
+ self._correct(lq2, False, pauli != Pauli.PauliX)
749
925
  if pauli != Pauli.PauliX:
750
926
  self._correct(lq2, True)
751
927
 
@@ -147,7 +147,11 @@ class QrackSystem:
147
147
  self.qrack_lib.set_device.argtypes = [c_ulonglong, c_longlong]
148
148
 
149
149
  self.qrack_lib.set_device_list.restype = None
150
- self.qrack_lib.set_device_list.argtypes = [c_ulonglong, c_ulonglong, POINTER(c_longlong)]
150
+ self.qrack_lib.set_device_list.argtypes = [
151
+ c_ulonglong,
152
+ c_ulonglong,
153
+ POINTER(c_longlong),
154
+ ]
151
155
 
152
156
  # pseudo-quantum
153
157
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyqrack-cpu-complex128
3
- Version: 1.58.0
3
+ Version: 1.58.10
4
4
  Summary: pyqrack - Pure Python vm6502q/qrack Wrapper
5
5
  Home-page: https://github.com/vm6502q/pyqrack
6
6
  Author: Daniel Strano
@@ -1,7 +1,7 @@
1
1
  pyqrack/__init__.py,sha256=3tBwfCCD-zQjQ2g1EUZdggKdn-3b2uSFTbT7LS0YLaU,785
2
2
  pyqrack/neuron_activation_fn.py,sha256=fQTTFfsvwcot_43Vopacot47IV2Rxk8pelUyuzwpXPs,593
3
3
  pyqrack/pauli.py,sha256=wg500wDOwdIU4lEVJoMmjtbAdmtakZYzLPjdzC2rwUQ,654
4
- pyqrack/qrack_ace_backend.py,sha256=S3epWZOsM0j38iXOmKn18vV2jtvDzf0IGMF6dVClK5o,43364
4
+ pyqrack/qrack_ace_backend.py,sha256=OLxjlPvGIrICawKFG87dlLtg9L77ZuVI_DT7RcyaIE8,48908
5
5
  pyqrack/qrack_circuit.py,sha256=vDCKGbcEHJDFUKprjCpWgit8lXFnMrPimKHURD2_Hj4,19538
6
6
  pyqrack/qrack_neuron.py,sha256=UiJdjAGB6usjAGHWSosSFCUUeIkhh3MtZbsaxfsIsNw,9043
7
7
  pyqrack/qrack_neuron_torch_layer.py,sha256=Bs5BLC2GFevfSpo_jSJ2AZl-hfDRJmzlGN9pFw1CtoQ,6160
@@ -9,15 +9,15 @@ pyqrack/qrack_simulator.py,sha256=2z4zGNPvDvVz2ctjeJl3jxUnKu0CxkABHvW5zxdUHa8,14
9
9
  pyqrack/qrack_stabilizer.py,sha256=O-7VJ9Vw4h25PK_kesSjIqHXGSo8lLrQLIyGgmzG7Co,2124
10
10
  pyqrack/quimb_circuit_type.py,sha256=Sk-Tmn38kUYmAkJJ75btWuhYZyTXOOezmowFhfdiGDc,621
11
11
  pyqrack/qrack_system/__init__.py,sha256=-oZ9dsb1hixsnrkUJRY_C5DzQ_l6MtifF_Z465BgqV4,334
12
- pyqrack/qrack_system/qrack_system.py,sha256=12HTwfhT7xN1jNB3wagQricZU0PL2-txAHZKxAYYu5M,42896
12
+ pyqrack/qrack_system/qrack_system.py,sha256=FWEMiBfDDoNIAo8jbqFR9MkvRGr6rOU_frvKGMgnTO8,42943
13
13
  pyqrack/qrack_system/qrack_cl_precompile/qrack_cl_precompile,sha256=8xQYqoFTKIl-5v6ZkqmbWp14Eowkl8ty2vNF2shC5hU,35040
14
14
  pyqrack/qrack_system/qrack_lib/libqrack_pinvoke.9.21.0.dylib,sha256=56UECwCa73rLbO65UvbPaTIqKrd4i56Gf4Jr6txNOJ0,3000968
15
15
  pyqrack/qrack_system/qrack_lib/libqrack_pinvoke.dylib,sha256=56UECwCa73rLbO65UvbPaTIqKrd4i56Gf4Jr6txNOJ0,3000968
16
16
  pyqrack/stats/__init__.py,sha256=Hla85my2fY_roR9lIjGBVpEG7ySOTMwjWa8D6-kgCnY,276
17
17
  pyqrack/stats/load_quantized_data.py,sha256=z12u9F7Nt3P-i44nY1xxvso_klS6WIHS3iqq7R2_lqE,1184
18
18
  pyqrack/stats/quantize_by_range.py,sha256=UM0_7jJDdQ7g30cR3UQAxkbzkqrmsy1oUfqg0h11FUY,2270
19
- pyqrack_cpu_complex128-1.58.0.dist-info/LICENSE,sha256=HxB-7SaWTuewAk1nz-3_3FUD6QhgX73kNT_taKVUTq8,1069
20
- pyqrack_cpu_complex128-1.58.0.dist-info/METADATA,sha256=O1AFXzY81JOii4hhT6S7LahC769-7JPCq2w4JjNtXF8,5921
21
- pyqrack_cpu_complex128-1.58.0.dist-info/WHEEL,sha256=nZx8s83OrgdDmpcWX-8FgI0sEAjdQimt4SdYsdcCaC8,107
22
- pyqrack_cpu_complex128-1.58.0.dist-info/top_level.txt,sha256=YE_3q9JTGRLMilNg2tGP1y7uU-Dx8PDao2OhwoIbv8E,8
23
- pyqrack_cpu_complex128-1.58.0.dist-info/RECORD,,
19
+ pyqrack_cpu_complex128-1.58.10.dist-info/LICENSE,sha256=HxB-7SaWTuewAk1nz-3_3FUD6QhgX73kNT_taKVUTq8,1069
20
+ pyqrack_cpu_complex128-1.58.10.dist-info/METADATA,sha256=z73HkCL5L8VeJZy9pEQRpqT7l956C2HXEjvr1XX2mKQ,5922
21
+ pyqrack_cpu_complex128-1.58.10.dist-info/WHEEL,sha256=nZx8s83OrgdDmpcWX-8FgI0sEAjdQimt4SdYsdcCaC8,107
22
+ pyqrack_cpu_complex128-1.58.10.dist-info/top_level.txt,sha256=YE_3q9JTGRLMilNg2tGP1y7uU-Dx8PDao2OhwoIbv8E,8
23
+ pyqrack_cpu_complex128-1.58.10.dist-info/RECORD,,