pyqrack-cpu 2.5.1__tar.gz → 2.7.0__tar.gz

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.
Files changed (30) hide show
  1. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/Makefile +1 -1
  2. {pyqrack_cpu-2.5.1/pyqrack_cpu.egg-info → pyqrack_cpu-2.7.0}/PKG-INFO +1 -1
  3. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/qrack_ace_backend.py +143 -19
  4. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/qrack_simulator.py +18 -10
  5. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/qrack_system/qrack_system.py +9 -0
  6. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0/pyqrack_cpu.egg-info}/PKG-INFO +1 -1
  7. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/setup.py +1 -1
  8. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/LICENSE +0 -0
  9. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/MANIFEST.in +0 -0
  10. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/README.md +0 -0
  11. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyproject.toml +0 -0
  12. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/__init__.py +0 -0
  13. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/neuron_activation_fn.py +0 -0
  14. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/pauli.py +0 -0
  15. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/qrack_circuit.py +0 -0
  16. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/qrack_near_clifford_qec_backend.py +0 -0
  17. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/qrack_neuron.py +0 -0
  18. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/qrack_neuron_torch_layer.py +0 -0
  19. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/qrack_stabilizer.py +0 -0
  20. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/qrack_system/__init__.py +0 -0
  21. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/quimb_circuit_type.py +0 -0
  22. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/stats/__init__.py +0 -0
  23. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/stats/load_quantized_data.py +0 -0
  24. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/stats/quantize_by_range.py +0 -0
  25. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack_cpu.egg-info/SOURCES.txt +0 -0
  26. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack_cpu.egg-info/dependency_links.txt +0 -0
  27. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack_cpu.egg-info/not-zip-safe +0 -0
  28. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack_cpu.egg-info/requires.txt +0 -0
  29. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack_cpu.egg-info/top_level.txt +0 -0
  30. {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/setup.cfg +0 -0
@@ -30,7 +30,7 @@ build-deps:
30
30
  rm -rf pyqrack/qrack_system/qrack_cl_precompile
31
31
  ifneq ($(OS),Windows_NT)
32
32
  ifeq ($(QRACK_PRESENT),)
33
- git clone https://github.com/unitaryfund/qrack.git; cd qrack; git checkout 01dbf96198e4df51cebcf23e506571cee0927244; cd ..
33
+ git clone https://github.com/unitaryfund/qrack.git; cd qrack; git checkout f407a468fa81ccb47e1a8ace3514ec689d03de4c; cd ..
34
34
  endif
35
35
  mkdir -p qrack/build
36
36
  ifeq ($(UNAME_S),Linux)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyqrack-cpu
3
- Version: 2.5.1
3
+ Version: 2.7.0
4
4
  Summary: pyqrack - Pure Python vm6502q/qrack Wrapper
5
5
  Home-page: https://github.com/vm6502q/pyqrack
6
6
  Author: Daniel Strano
@@ -9,6 +9,7 @@ import os
9
9
  import random
10
10
  import sys
11
11
  import time
12
+ from collections import deque
12
13
 
13
14
  from .qrack_simulator import QrackSimulator
14
15
  from .pauli import Pauli
@@ -230,6 +231,7 @@ class QrackAceBackend:
230
231
  is_host_pointer=(True if os.environ.get("PYQRACK_HOST_POINTER_DEFAULT_ON") else False),
231
232
  is_near_clifford_tableau_writer=False,
232
233
  noise=0,
234
+ history_window=0,
233
235
  to_clone=None,
234
236
  ):
235
237
  if to_clone:
@@ -237,15 +239,19 @@ class QrackAceBackend:
237
239
  long_range_columns = to_clone.long_range_columns
238
240
  long_range_rows = to_clone.long_range_rows
239
241
  is_transpose = to_clone.is_transpose
242
+ history_window = to_clone.history_window
240
243
  if qubit_count < 0:
241
244
  qubit_count = 0
242
245
  if long_range_columns < 0:
243
246
  long_range_columns = 0
247
+ if history_window < 0:
248
+ history_window = 0
244
249
 
245
250
  self._factor_width(qubit_count, is_transpose)
246
251
  self.long_range_columns = long_range_columns
247
252
  self.long_range_rows = long_range_rows
248
253
  self.is_transpose = is_transpose
254
+ self.history_window = history_window
249
255
 
250
256
  fppow = 5
251
257
  if "QRACK_FPPOW" in os.environ:
@@ -295,6 +301,22 @@ class QrackAceBackend:
295
301
 
296
302
  self._qubits = []
297
303
  self._lhv = {}
304
+ if self.history_window > 0:
305
+ if to_clone and to_clone._coupling_history is not None:
306
+ self._coupling_history = {
307
+ k: deque(v, maxlen=self.history_window)
308
+ for k, v in to_clone._coupling_history.items()
309
+ }
310
+ self._coupling_history_rev = dict(to_clone._coupling_history_rev)
311
+ self._pending_skip = {k: set(v) for k, v in to_clone._pending_skip.items()}
312
+ else:
313
+ self._coupling_history = {}
314
+ self._coupling_history_rev = {}
315
+ self._pending_skip = {}
316
+ else:
317
+ self._coupling_history = None
318
+ self._coupling_history_rev = None
319
+ self._pending_skip = None
298
320
  sim_counts = [0] * sim_count
299
321
  sim_id = 0
300
322
  tot_qubits = 0
@@ -864,14 +886,17 @@ class QrackAceBackend:
864
886
  hq = self._unpack(lq)
865
887
  if len(hq) < 2:
866
888
  b = hq[0]
889
+ self._invalidate_for_gate(lq)
867
890
  self.sim[b[0]].u(b[1], th, ph, lm)
868
891
  return
869
892
 
893
+ skip = self._invalidate_for_gate(lq)
870
894
  qb, _ = QrackAceBackend._get_qb_lhv_indices(hq)
871
895
 
872
896
  for q in qb:
873
897
  b = hq[q]
874
- self.sim[b[0]].u(b[1], th, ph, lm)
898
+ if (b[0], b[1]) not in skip:
899
+ self.sim[b[0]].u(b[1], th, ph, lm)
875
900
 
876
901
  lhv = self._lhv.get(lq)
877
902
  if lhv is not None:
@@ -879,18 +904,85 @@ class QrackAceBackend:
879
904
 
880
905
  # Correction deferred to next 2-qubit gate (_cpauli calls _correct)
881
906
 
907
+ def _revert_shadow_commitment(self, lq1):
908
+ """Revert shadow-committed replicas recorded under lq1. H-reverts
909
+ each committed shadow replica (undoing the stale Z-basis commitment),
910
+ stores the reverted tuples in _pending_skip[lq2] so the NEXT gate on
911
+ that boundary qubit skips those replicas entirely (rotating an H-reverted
912
+ shadow replica from the wrong starting state gives a wrong result; the
913
+ right behavior is to skip it and let the next coupling gate re-derive
914
+ from scratch), and returns the reverted set for the immediate caller to
915
+ skip as well (for case A, where the control's own rotation should also
916
+ skip its own shadow replicas that were just un-committed)."""
917
+ if self._coupling_history is None:
918
+ return set()
919
+ hist = self._coupling_history.pop(lq1, None)
920
+ if hist is None:
921
+ return set()
922
+ reverted_all = set()
923
+ for lq2, targets in hist:
924
+ reverted = set()
925
+ for t_sim, t_idx in targets:
926
+ self.sim[t_sim].h(t_idx)
927
+ reverted.add((t_sim, t_idx))
928
+ # Store as pending skip for the NEXT gate on lq2 (case B):
929
+ # when the boundary qubit's own gate runs, it should skip
930
+ # these replicas rather than applying its gate to the freshly-
931
+ # H-reverted, uncommitted state.
932
+ if reverted:
933
+ existing = self._pending_skip.get(lq2, set())
934
+ self._pending_skip[lq2] = existing | reverted
935
+ self._coupling_history_rev.pop(lq2, None)
936
+ reverted_all |= reverted
937
+ return reverted_all
938
+
939
+ def _invalidate_for_gate(self, lq):
940
+ """Called by every single-qubit gate dispatcher. Returns the set of
941
+ (sim_id, idx) shadow replicas that should be SKIPPED in the calling
942
+ gate's own application loop.
943
+ - Case A: lq is the coherent-partner (lq1) in a live history entry.
944
+ A gate on the control side invalidates the shadow commitment: reverts
945
+ the shadow targets via H (returning them to uncommitted 0.5), stores
946
+ them in pending_skip[lq2] for the NEXT gate on the boundary qubit,
947
+ and returns them for the immediate caller to skip as well (since the
948
+ control's own replica at slot0 may also be in the reverted set).
949
+ - Case B: lq is the boundary recipient (lq2) of a commitment that a
950
+ prior case-A revert already H-reverted. Consumes the pending_skip
951
+ set so the boundary gate doesn't apply itself to the freshly-
952
+ uncommitted replicas (which would give the wrong result from the
953
+ wrong starting state). Case B NEVER triggers a fresh revert --
954
+ only case A does, because only a gate on the control side actually
955
+ invalidates the commitment; a gate on the boundary side just needs
956
+ to avoid corrupting the already-reverted starting state."""
957
+ if self._coupling_history is None:
958
+ return set()
959
+ skip = set()
960
+ # Case A: lq is the coherent control side -- fire the revert.
961
+ if lq in self._coupling_history:
962
+ skip |= self._revert_shadow_commitment(lq)
963
+ # Case B: lq is the boundary side -- ONLY consume pending_skip,
964
+ # never trigger a fresh revert (that would incorrectly revert
965
+ # a still-valid commitment that no control-side gate has touched).
966
+ pending = self._pending_skip.pop(lq, None)
967
+ if pending:
968
+ skip |= pending
969
+ return skip
970
+
882
971
  def r(self, p, th, lq):
883
972
  hq = self._unpack(lq)
884
973
  if len(hq) < 2:
885
974
  b = hq[0]
975
+ self._invalidate_for_gate(lq)
886
976
  self.sim[b[0]].r(p, th, b[1])
887
977
  return
888
978
 
889
979
  qb, _ = QrackAceBackend._get_qb_lhv_indices(hq)
980
+ skip = self._invalidate_for_gate(lq)
890
981
 
891
982
  for q in qb:
892
983
  b = hq[q]
893
- self.sim[b[0]].r(p, th, b[1])
984
+ if (b[0], b[1]) not in skip:
985
+ self.sim[b[0]].r(p, th, b[1])
894
986
 
895
987
  lhv = self._lhv.get(lq)
896
988
  if lhv is not None:
@@ -907,16 +999,19 @@ class QrackAceBackend:
907
999
  hq = self._unpack(lq)
908
1000
  if len(hq) < 2:
909
1001
  b = hq[0]
1002
+ self._invalidate_for_gate(lq)
910
1003
  self.sim[b[0]].h(b[1])
911
1004
  return
912
1005
 
913
1006
  self._correct(lq)
1007
+ skip = self._invalidate_for_gate(lq)
914
1008
 
915
1009
  qb, _ = QrackAceBackend._get_qb_lhv_indices(hq)
916
1010
 
917
1011
  for q in qb:
918
1012
  b = hq[q]
919
- self.sim[b[0]].h(b[1])
1013
+ if (b[0], b[1]) not in skip:
1014
+ self.sim[b[0]].h(b[1])
920
1015
 
921
1016
  lhv = self._lhv.get(lq)
922
1017
  if lhv is not None:
@@ -928,14 +1023,17 @@ class QrackAceBackend:
928
1023
  hq = self._unpack(lq)
929
1024
  if len(hq) < 2:
930
1025
  b = hq[0]
1026
+ self._invalidate_for_gate(lq)
931
1027
  self.sim[b[0]].s(b[1])
932
1028
  return
933
1029
 
1030
+ skip = self._invalidate_for_gate(lq)
934
1031
  qb, _ = QrackAceBackend._get_qb_lhv_indices(hq)
935
1032
 
936
1033
  for q in qb:
937
1034
  b = hq[q]
938
- self.sim[b[0]].s(b[1])
1035
+ if (b[0], b[1]) not in skip:
1036
+ self.sim[b[0]].s(b[1])
939
1037
 
940
1038
  lhv = self._lhv.get(lq)
941
1039
  if lhv is not None:
@@ -945,14 +1043,17 @@ class QrackAceBackend:
945
1043
  hq = self._unpack(lq)
946
1044
  if len(hq) < 2:
947
1045
  b = hq[0]
1046
+ self._invalidate_for_gate(lq)
948
1047
  self.sim[b[0]].adjs(b[1])
949
1048
  return
950
1049
 
1050
+ skip = self._invalidate_for_gate(lq)
951
1051
  qb, _ = QrackAceBackend._get_qb_lhv_indices(hq)
952
1052
 
953
1053
  for q in qb:
954
1054
  b = hq[q]
955
- self.sim[b[0]].adjs(b[1])
1055
+ if (b[0], b[1]) not in skip:
1056
+ self.sim[b[0]].adjs(b[1])
956
1057
 
957
1058
  lhv = self._lhv.get(lq)
958
1059
  if lhv is not None:
@@ -962,14 +1063,17 @@ class QrackAceBackend:
962
1063
  hq = self._unpack(lq)
963
1064
  if len(hq) < 2:
964
1065
  b = hq[0]
1066
+ self._invalidate_for_gate(lq)
965
1067
  self.sim[b[0]].x(b[1])
966
1068
  return
967
1069
 
1070
+ skip = self._invalidate_for_gate(lq)
968
1071
  qb, _ = QrackAceBackend._get_qb_lhv_indices(hq)
969
1072
 
970
1073
  for q in qb:
971
1074
  b = hq[q]
972
- self.sim[b[0]].x(b[1])
1075
+ if (b[0], b[1]) not in skip:
1076
+ self.sim[b[0]].x(b[1])
973
1077
 
974
1078
  lhv = self._lhv.get(lq)
975
1079
  if lhv is not None:
@@ -979,14 +1083,17 @@ class QrackAceBackend:
979
1083
  hq = self._unpack(lq)
980
1084
  if len(hq) < 2:
981
1085
  b = hq[0]
1086
+ self._invalidate_for_gate(lq)
982
1087
  self.sim[b[0]].y(b[1])
983
1088
  return
984
1089
 
1090
+ skip = self._invalidate_for_gate(lq)
985
1091
  qb, _ = QrackAceBackend._get_qb_lhv_indices(hq)
986
1092
 
987
1093
  for q in qb:
988
1094
  b = hq[q]
989
- self.sim[b[0]].y(b[1])
1095
+ if (b[0], b[1]) not in skip:
1096
+ self.sim[b[0]].y(b[1])
990
1097
 
991
1098
  lhv = self._lhv.get(lq)
992
1099
  if lhv is not None:
@@ -996,14 +1103,17 @@ class QrackAceBackend:
996
1103
  hq = self._unpack(lq)
997
1104
  if len(hq) < 2:
998
1105
  b = hq[0]
1106
+ self._invalidate_for_gate(lq)
999
1107
  self.sim[b[0]].z(b[1])
1000
1108
  return
1001
1109
 
1110
+ skip = self._invalidate_for_gate(lq)
1002
1111
  qb, _ = QrackAceBackend._get_qb_lhv_indices(hq)
1003
1112
 
1004
1113
  for q in qb:
1005
1114
  b = hq[q]
1006
- self.sim[b[0]].z(b[1])
1115
+ if (b[0], b[1]) not in skip:
1116
+ self.sim[b[0]].z(b[1])
1007
1117
 
1008
1118
  lhv = self._lhv.get(lq)
1009
1119
  if lhv is not None:
@@ -1013,14 +1123,17 @@ class QrackAceBackend:
1013
1123
  hq = self._unpack(lq)
1014
1124
  if len(hq) < 2:
1015
1125
  b = hq[0]
1126
+ self._invalidate_for_gate(lq)
1016
1127
  self.sim[b[0]].t(b[1])
1017
1128
  return
1018
1129
 
1130
+ skip = self._invalidate_for_gate(lq)
1019
1131
  qb, _ = QrackAceBackend._get_qb_lhv_indices(hq)
1020
1132
 
1021
1133
  for q in qb:
1022
1134
  b = hq[q]
1023
- self.sim[b[0]].t(b[1])
1135
+ if (b[0], b[1]) not in skip:
1136
+ self.sim[b[0]].t(b[1])
1024
1137
 
1025
1138
  lhv = self._lhv.get(lq)
1026
1139
  if lhv is not None:
@@ -1030,14 +1143,17 @@ class QrackAceBackend:
1030
1143
  hq = self._unpack(lq)
1031
1144
  if len(hq) < 2:
1032
1145
  b = hq[0]
1146
+ self._invalidate_for_gate(lq)
1033
1147
  self.sim[b[0]].adjt(b[1])
1034
1148
  return
1035
1149
 
1150
+ skip = self._invalidate_for_gate(lq)
1036
1151
  qb, _ = QrackAceBackend._get_qb_lhv_indices(hq)
1037
1152
 
1038
1153
  for q in qb:
1039
1154
  b = hq[q]
1040
- self.sim[b[0]].adjt(b[1])
1155
+ if (b[0], b[1]) not in skip:
1156
+ self.sim[b[0]].adjt(b[1])
1041
1157
 
1042
1158
  lhv = self._lhv.get(lq)
1043
1159
  if lhv is not None:
@@ -1081,7 +1197,8 @@ class QrackAceBackend:
1081
1197
 
1082
1198
  return connected, boundary
1083
1199
 
1084
- def _apply_coupling(self, pauli, anti, qb1, hq1, qb2, hq2, lq1_lr):
1200
+ def _apply_coupling(self, pauli, anti, qb1, hq1, qb2, hq2, lq1_lr, lq1=None, lq2=None):
1201
+ shadow_targets = []
1085
1202
  for q1 in qb1:
1086
1203
  b1 = hq1[q1]
1087
1204
  gate_fn, shadow_fn = self._get_gate(pauli, anti, b1[0])
@@ -1091,6 +1208,20 @@ class QrackAceBackend:
1091
1208
  gate_fn([b1[1]], b2[1])
1092
1209
  elif lq1_lr or (b1[1] == b2[1]) or ((len(qb1) == 2) and (b1[1] == (b2[1] & 1))):
1093
1210
  shadow_fn(b1, b2)
1211
+ shadow_targets.append(b2)
1212
+
1213
+ if (
1214
+ self._coupling_history is not None
1215
+ and lq1 is not None
1216
+ and lq2 is not None
1217
+ and shadow_targets
1218
+ ):
1219
+ entry = (lq2, tuple(shadow_targets))
1220
+ hist = self._coupling_history.setdefault(
1221
+ lq1, deque(maxlen=self.history_window)
1222
+ )
1223
+ hist.append(entry)
1224
+ self._coupling_history_rev[lq2] = lq1
1094
1225
 
1095
1226
  def _cpauli(self, lq1, lq2, anti, pauli):
1096
1227
  lq1_row = lq1 // self._row_length
@@ -1110,7 +1241,7 @@ class QrackAceBackend:
1110
1241
  qb2, _ = QrackAceBackend._get_qb_lhv_indices(hq2)
1111
1242
  # Apply cross coupling on every qubit, including former-LHV boundary
1112
1243
  # qubits, which now live as real qubits in the shared boundary sim.
1113
- self._apply_coupling(pauli, anti, qb1, hq1, qb2, hq2, lq1_lr)
1244
+ self._apply_coupling(pauli, anti, qb1, hq1, qb2, hq2, lq1_lr, lq1, lq2)
1114
1245
 
1115
1246
  if lq2 in self._lhv:
1116
1247
  ctrl_prob = self.sim[hq1[0][0]].prob(hq1[0][1])
@@ -1642,10 +1773,6 @@ class QrackAceBackend:
1642
1773
  return [
1643
1774
  "id",
1644
1775
  "u",
1645
- "u1",
1646
- "u2",
1647
- "u3",
1648
- "r",
1649
1776
  "rx",
1650
1777
  "ry",
1651
1778
  "rz",
@@ -1655,9 +1782,6 @@ class QrackAceBackend:
1655
1782
  "z",
1656
1783
  "s",
1657
1784
  "sdg",
1658
- "sx",
1659
- "sxdg",
1660
- "p",
1661
1785
  "t",
1662
1786
  "tdg",
1663
1787
  "cx",
@@ -3202,9 +3202,26 @@ class QrackSimulator:
3202
3202
  Raises:
3203
3203
  Runtimeerror: QrackSimulator raised an exception.
3204
3204
  """
3205
- result = Qrack.qrack_lib.Separate(self.sid, len(qs), QrackSimulator._ulonglong_byref(qs))
3205
+ Qrack.qrack_lib.Separate(self.sid, len(qs), QrackSimulator._ulonglong_byref(qs))
3206
3206
  self._throw_if_error()
3207
3207
 
3208
+ def are_factorized(self, a, b):
3209
+ """Check whether bits in "a" are factorized from bits in "b"
3210
+
3211
+ After flushing all buffers, check whether "a" set of qubits is factorized separate from "b" set of qubits
3212
+
3213
+ Args:
3214
+ a: first list of qubits
3215
+ b: second list of qubits
3216
+
3217
+ Raises:
3218
+ Runtimeerror: QrackSimulator raised an exception.
3219
+ """
3220
+ result = Qrack.qrack_lib.AreFactorized(self.sid, len(a), QrackSimulator._ulonglong_byref(a), len(b), QrackSimulator._ulonglong_byref(b))
3221
+ self._throw_if_error()
3222
+
3223
+ return result
3224
+
3208
3225
  def get_unitary_fidelity(self):
3209
3226
  """Get fidelity estimate
3210
3227
 
@@ -4499,10 +4516,6 @@ class QrackSimulator:
4499
4516
  return [
4500
4517
  "id",
4501
4518
  "u",
4502
- "u1",
4503
- "u2",
4504
- "u3",
4505
- "r",
4506
4519
  "rx",
4507
4520
  "ry",
4508
4521
  "rz",
@@ -4512,14 +4525,9 @@ class QrackSimulator:
4512
4525
  "z",
4513
4526
  "s",
4514
4527
  "sdg",
4515
- "sx",
4516
- "sxdg",
4517
- "p",
4518
4528
  "t",
4519
4529
  "tdg",
4520
4530
  "cu",
4521
- "cu1",
4522
- "cu3",
4523
4531
  "cx",
4524
4532
  "cy",
4525
4533
  "cz",
@@ -1204,6 +1204,15 @@ class QrackSystem:
1204
1204
  POINTER(c_ulonglong),
1205
1205
  ]
1206
1206
 
1207
+ self.qrack_lib.AreFactorized.restype = c_bool
1208
+ self.qrack_lib.AreFactorized.argtypes = [
1209
+ c_ulonglong,
1210
+ c_ulonglong,
1211
+ POINTER(c_ulonglong),
1212
+ c_ulonglong,
1213
+ POINTER(c_ulonglong),
1214
+ ]
1215
+
1207
1216
  self.qrack_lib.GetUnitaryFidelity.restype = c_double
1208
1217
  self.qrack_lib.GetUnitaryFidelity.argtypes = [c_ulonglong]
1209
1218
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyqrack-cpu
3
- Version: 2.5.1
3
+ Version: 2.7.0
4
4
  Summary: pyqrack - Pure Python vm6502q/qrack Wrapper
5
5
  Home-page: https://github.com/vm6502q/pyqrack
6
6
  Author: Daniel Strano
@@ -7,7 +7,7 @@ from setuptools import setup
7
7
  from setuptools.command.build_py import build_py
8
8
 
9
9
 
10
- VERSION = "2.5.1"
10
+ VERSION = "2.7.0"
11
11
 
12
12
  # Read long description from README.
13
13
  README_PATH = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'README.md')
File without changes
File without changes
File without changes
File without changes
File without changes