pyqrack-cpu 1.44.8__py3-none-win_amd64.whl → 1.44.9__py3-none-win_amd64.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 might be problematic. Click here for more details.
- pyqrack/__init__.py +5 -1
- pyqrack/neuron_activation_fn.py +1 -1
- pyqrack/qrack_ace_backend.py +77 -100
- pyqrack/qrack_circuit.py +67 -39
- pyqrack/qrack_neuron.py +25 -8
- pyqrack/qrack_neuron_torch_layer.py +46 -19
- pyqrack/qrack_simulator.py +547 -211
- pyqrack/qrack_stabilizer.py +1 -2
- pyqrack/qrack_system/qrack_lib/qrack_pinvoke.dll +0 -0
- pyqrack/qrack_system/qrack_system.py +161 -119
- pyqrack/stats/load_quantized_data.py +3 -1
- pyqrack/stats/quantize_by_range.py +9 -4
- {pyqrack_cpu-1.44.8.dist-info → pyqrack_cpu-1.44.9.dist-info}/METADATA +1 -1
- pyqrack_cpu-1.44.9.dist-info/RECORD +21 -0
- pyqrack_cpu-1.44.8.dist-info/RECORD +0 -21
- {pyqrack_cpu-1.44.8.dist-info → pyqrack_cpu-1.44.9.dist-info}/LICENSE +0 -0
- {pyqrack_cpu-1.44.8.dist-info → pyqrack_cpu-1.44.9.dist-info}/WHEEL +0 -0
- {pyqrack_cpu-1.44.8.dist-info → pyqrack_cpu-1.44.9.dist-info}/top_level.txt +0 -0
pyqrack/qrack_simulator.py
CHANGED
|
@@ -57,7 +57,9 @@ class QrackSimulator:
|
|
|
57
57
|
isPaged=True,
|
|
58
58
|
isCpuGpuHybrid=True,
|
|
59
59
|
isOpenCL=True,
|
|
60
|
-
isHostPointer=
|
|
60
|
+
isHostPointer=(
|
|
61
|
+
True if os.environ.get("PYQRACK_HOST_POINTER_DEFAULT_ON") else False
|
|
62
|
+
),
|
|
61
63
|
noise=0,
|
|
62
64
|
pyzxCircuit=None,
|
|
63
65
|
qiskitCircuit=None,
|
|
@@ -96,7 +98,7 @@ class QrackSimulator:
|
|
|
96
98
|
(noise > 0),
|
|
97
99
|
isCpuGpuHybrid,
|
|
98
100
|
isOpenCL,
|
|
99
|
-
isHostPointer
|
|
101
|
+
isHostPointer,
|
|
100
102
|
)
|
|
101
103
|
|
|
102
104
|
self._throw_if_error()
|
|
@@ -340,7 +342,9 @@ class QrackSimulator:
|
|
|
340
342
|
RuntimeError: QrackSimulator raised an exception.
|
|
341
343
|
"""
|
|
342
344
|
if len(m) < 4:
|
|
343
|
-
raise ValueError(
|
|
345
|
+
raise ValueError(
|
|
346
|
+
"2x2 matrix 'm' in QrackSimulator.mtrx() must contain at least 4 elements."
|
|
347
|
+
)
|
|
344
348
|
Qrack.qrack_lib.Mtrx(self.sid, self._complex_byref(m), q)
|
|
345
349
|
self._throw_if_error()
|
|
346
350
|
|
|
@@ -558,7 +562,9 @@ class QrackSimulator:
|
|
|
558
562
|
RuntimeError: QrackSimulator raised an exception.
|
|
559
563
|
"""
|
|
560
564
|
if len(m) < 4:
|
|
561
|
-
raise ValueError(
|
|
565
|
+
raise ValueError(
|
|
566
|
+
"2x2 matrix 'm' in QrackSimulator.mcmtrx() must contain at least 4 elements."
|
|
567
|
+
)
|
|
562
568
|
Qrack.qrack_lib.MCMtrx(
|
|
563
569
|
self.sid, len(c), self._ulonglong_byref(c), self._complex_byref(m), q
|
|
564
570
|
)
|
|
@@ -734,7 +740,9 @@ class QrackSimulator:
|
|
|
734
740
|
RuntimeError: QrackSimulator raised an exception.
|
|
735
741
|
"""
|
|
736
742
|
if len(m) < 4:
|
|
737
|
-
raise ValueError(
|
|
743
|
+
raise ValueError(
|
|
744
|
+
"2x2 matrix 'm' in QrackSimulator.macmtrx() must contain at least 4 elements."
|
|
745
|
+
)
|
|
738
746
|
Qrack.qrack_lib.MACMtrx(
|
|
739
747
|
self.sid, len(c), self._ulonglong_byref(c), self._complex_byref(m), q
|
|
740
748
|
)
|
|
@@ -757,7 +765,9 @@ class QrackSimulator:
|
|
|
757
765
|
RuntimeError: QrackSimulator raised an exception.
|
|
758
766
|
"""
|
|
759
767
|
if len(m) < 4:
|
|
760
|
-
raise ValueError(
|
|
768
|
+
raise ValueError(
|
|
769
|
+
"2x2 matrix 'm' in QrackSimulator.ucmtrx() must contain at least 4 elements."
|
|
770
|
+
)
|
|
761
771
|
Qrack.qrack_lib.UCMtrx(
|
|
762
772
|
self.sid, len(c), self._ulonglong_byref(c), self._complex_byref(m), q, p
|
|
763
773
|
)
|
|
@@ -779,7 +789,9 @@ class QrackSimulator:
|
|
|
779
789
|
RuntimeError: QrackSimulator raised an exception.
|
|
780
790
|
"""
|
|
781
791
|
if len(m) < ((1 << len(c)) * 4):
|
|
782
|
-
raise ValueError(
|
|
792
|
+
raise ValueError(
|
|
793
|
+
"Multiplex matrix 'm' in QrackSimulator.multiplex1_mtrx() must contain at least (4 * 2 ** len(c)) elements."
|
|
794
|
+
)
|
|
783
795
|
Qrack.qrack_lib.Multiplex1Mtrx(
|
|
784
796
|
self.sid, len(c), self._ulonglong_byref(c), q, self._complex_byref(m)
|
|
785
797
|
)
|
|
@@ -1249,9 +1261,13 @@ class QrackSimulator:
|
|
|
1249
1261
|
RuntimeError: QrackSimulator with isTensorNetwork=True option cannot mul()! (Turn off just this option, in the constructor.)
|
|
1250
1262
|
"""
|
|
1251
1263
|
if self.is_tensor_network:
|
|
1252
|
-
raise RuntimeError(
|
|
1264
|
+
raise RuntimeError(
|
|
1265
|
+
"QrackSimulator with isTensorNetwork=True option cannot mul()! (Turn off just this option, in the constructor.)"
|
|
1266
|
+
)
|
|
1253
1267
|
if self.is_pure_stabilizer:
|
|
1254
|
-
raise RuntimeError(
|
|
1268
|
+
raise RuntimeError(
|
|
1269
|
+
"QrackStabilizer cannot mul()! (Create a QrackSimulator instead, also with isTensorNetwork=False.)"
|
|
1270
|
+
)
|
|
1255
1271
|
|
|
1256
1272
|
if len(q) != len(o):
|
|
1257
1273
|
raise RuntimeError("Lengths of list parameters are mismatched.")
|
|
@@ -1284,9 +1300,13 @@ class QrackSimulator:
|
|
|
1284
1300
|
RuntimeError: QrackSimulator with isTensorNetwork=True option cannot div()! (Turn off just this option, in the constructor.)
|
|
1285
1301
|
"""
|
|
1286
1302
|
if self.is_tensor_network:
|
|
1287
|
-
raise RuntimeError(
|
|
1303
|
+
raise RuntimeError(
|
|
1304
|
+
"QrackSimulator with isTensorNetwork=True option cannot div()! (Turn off just this option, in the constructor.)"
|
|
1305
|
+
)
|
|
1288
1306
|
if self.is_pure_stabilizer:
|
|
1289
|
-
raise RuntimeError(
|
|
1307
|
+
raise RuntimeError(
|
|
1308
|
+
"QrackStabilizer cannot div()! (Create a QrackSimulator instead, also with isTensorNetwork=False.)"
|
|
1309
|
+
)
|
|
1290
1310
|
|
|
1291
1311
|
if len(q) != len(o):
|
|
1292
1312
|
raise RuntimeError("Lengths of list parameters are mismatched.")
|
|
@@ -1377,9 +1397,13 @@ class QrackSimulator:
|
|
|
1377
1397
|
RuntimeError: QrackSimulator with isTensorNetwork=True option cannot pown()! (Turn off just this option, in the constructor.)
|
|
1378
1398
|
"""
|
|
1379
1399
|
if self.is_tensor_network:
|
|
1380
|
-
raise RuntimeError(
|
|
1400
|
+
raise RuntimeError(
|
|
1401
|
+
"QrackSimulator with isTensorNetwork=True option cannot pown()! (Turn off just this option, in the constructor.)"
|
|
1402
|
+
)
|
|
1381
1403
|
if self.is_pure_stabilizer:
|
|
1382
|
-
raise RuntimeError(
|
|
1404
|
+
raise RuntimeError(
|
|
1405
|
+
"QrackStabilizer cannot pown()! (Create a QrackSimulator instead, also with isTensorNetwork=False.)"
|
|
1406
|
+
)
|
|
1383
1407
|
|
|
1384
1408
|
if len(q) != len(o):
|
|
1385
1409
|
raise RuntimeError("Lengths of list parameters are mismatched.")
|
|
@@ -1466,9 +1490,13 @@ class QrackSimulator:
|
|
|
1466
1490
|
RuntimeError: QrackSimulator with isTensorNetwork=True option cannot mcmul()! (Turn off just this option, in the constructor.)
|
|
1467
1491
|
"""
|
|
1468
1492
|
if self.is_tensor_network:
|
|
1469
|
-
raise RuntimeError(
|
|
1493
|
+
raise RuntimeError(
|
|
1494
|
+
"QrackSimulator with isTensorNetwork=True option cannot mcmul()! (Turn off just this option, in the constructor.)"
|
|
1495
|
+
)
|
|
1470
1496
|
if self.is_pure_stabilizer:
|
|
1471
|
-
raise RuntimeError(
|
|
1497
|
+
raise RuntimeError(
|
|
1498
|
+
"QrackStabilizer cannot mcmul()! (Create a QrackSimulator instead, also with isTensorNetwork=False.)"
|
|
1499
|
+
)
|
|
1472
1500
|
|
|
1473
1501
|
if len(q) != len(o):
|
|
1474
1502
|
raise RuntimeError("Lengths of list parameters are mismatched.")
|
|
@@ -1504,9 +1532,13 @@ class QrackSimulator:
|
|
|
1504
1532
|
RuntimeError: QrackSimulator with isTensorNetwork=True option cannot mcdiv()! (Turn off just this option, in the constructor.)
|
|
1505
1533
|
"""
|
|
1506
1534
|
if self.is_tensor_network:
|
|
1507
|
-
raise RuntimeError(
|
|
1535
|
+
raise RuntimeError(
|
|
1536
|
+
"QrackSimulator with isTensorNetwork=True option cannot mcdiv()! (Turn off just this option, in the constructor.)"
|
|
1537
|
+
)
|
|
1508
1538
|
if self.is_pure_stabilizer:
|
|
1509
|
-
raise RuntimeError(
|
|
1539
|
+
raise RuntimeError(
|
|
1540
|
+
"QrackStabilizer cannot mcdiv()! (Create a QrackSimulator instead, also with isTensorNetwork=False.)"
|
|
1541
|
+
)
|
|
1510
1542
|
|
|
1511
1543
|
if len(q) != len(o):
|
|
1512
1544
|
raise RuntimeError("Lengths of list parameters are mismatched.")
|
|
@@ -1608,9 +1640,13 @@ class QrackSimulator:
|
|
|
1608
1640
|
RuntimeError: QrackSimulator with isTensorNetwork=True option cannot mcpown()! (Turn off just this option, in the constructor.)
|
|
1609
1641
|
"""
|
|
1610
1642
|
if self.is_tensor_network:
|
|
1611
|
-
raise RuntimeError(
|
|
1643
|
+
raise RuntimeError(
|
|
1644
|
+
"QrackSimulator with isTensorNetwork=True option cannot mcpown()! (Turn off just this option, in the constructor.)"
|
|
1645
|
+
)
|
|
1612
1646
|
if self.is_pure_stabilizer:
|
|
1613
|
-
raise RuntimeError(
|
|
1647
|
+
raise RuntimeError(
|
|
1648
|
+
"QrackStabilizer cannot mcpown()! (Create a QrackSimulator instead, also with isTensorNetwork=False.)"
|
|
1649
|
+
)
|
|
1614
1650
|
|
|
1615
1651
|
if len(q) != len(o):
|
|
1616
1652
|
raise RuntimeError("Lengths of list parameters are mismatched.")
|
|
@@ -1645,9 +1681,13 @@ class QrackSimulator:
|
|
|
1645
1681
|
RuntimeError: QrackSimulator with isTensorNetwork=True option cannot lda()! (Turn off just this option, in the constructor.)
|
|
1646
1682
|
"""
|
|
1647
1683
|
if self.is_tensor_network:
|
|
1648
|
-
raise RuntimeError(
|
|
1684
|
+
raise RuntimeError(
|
|
1685
|
+
"QrackSimulator with isTensorNetwork=True option cannot lda()! (Turn off just this option, in the constructor.)"
|
|
1686
|
+
)
|
|
1649
1687
|
if self.is_pure_stabilizer:
|
|
1650
|
-
raise RuntimeError(
|
|
1688
|
+
raise RuntimeError(
|
|
1689
|
+
"QrackStabilizer cannot lda()! (Create a QrackSimulator instead, also with isTensorNetwork=False.)"
|
|
1690
|
+
)
|
|
1651
1691
|
|
|
1652
1692
|
Qrack.qrack_lib.LDA(
|
|
1653
1693
|
self.sid,
|
|
@@ -1675,9 +1715,13 @@ class QrackSimulator:
|
|
|
1675
1715
|
RuntimeError: QrackSimulator with isTensorNetwork=True option cannot adc()! (Turn off just this option, in the constructor.)
|
|
1676
1716
|
"""
|
|
1677
1717
|
if self.is_tensor_network:
|
|
1678
|
-
raise RuntimeError(
|
|
1718
|
+
raise RuntimeError(
|
|
1719
|
+
"QrackSimulator with isTensorNetwork=True option cannot adc()! (Turn off just this option, in the constructor.)"
|
|
1720
|
+
)
|
|
1679
1721
|
if self.is_pure_stabilizer:
|
|
1680
|
-
raise RuntimeError(
|
|
1722
|
+
raise RuntimeError(
|
|
1723
|
+
"QrackStabilizer cannot adc()! (Create a QrackSimulator instead, also with isTensorNetwork=False.)"
|
|
1724
|
+
)
|
|
1681
1725
|
|
|
1682
1726
|
Qrack.qrack_lib.ADC(
|
|
1683
1727
|
self.sid,
|
|
@@ -1706,9 +1750,13 @@ class QrackSimulator:
|
|
|
1706
1750
|
RuntimeError: QrackSimulator with isTensorNetwork=True option cannot sbc()! (Turn off just this option, in the constructor.)
|
|
1707
1751
|
"""
|
|
1708
1752
|
if self.is_tensor_network:
|
|
1709
|
-
raise RuntimeError(
|
|
1753
|
+
raise RuntimeError(
|
|
1754
|
+
"QrackSimulator with isTensorNetwork=True option cannot sbc()! (Turn off just this option, in the constructor.)"
|
|
1755
|
+
)
|
|
1710
1756
|
if self.is_pure_stabilizer:
|
|
1711
|
-
raise RuntimeError(
|
|
1757
|
+
raise RuntimeError(
|
|
1758
|
+
"QrackStabilizer cannot sbc()! (Create a QrackSimulator instead, also with isTensorNetwork=False.)"
|
|
1759
|
+
)
|
|
1712
1760
|
|
|
1713
1761
|
Qrack.qrack_lib.SBC(
|
|
1714
1762
|
self.sid,
|
|
@@ -1738,9 +1786,13 @@ class QrackSimulator:
|
|
|
1738
1786
|
RuntimeError: QrackSimulator with isTensorNetwork=True option cannot hash()! (Turn off just this option, in the constructor.)
|
|
1739
1787
|
"""
|
|
1740
1788
|
if self.is_tensor_network:
|
|
1741
|
-
raise RuntimeError(
|
|
1789
|
+
raise RuntimeError(
|
|
1790
|
+
"QrackSimulator with isTensorNetwork=True option cannot hash()! (Turn off just this option, in the constructor.)"
|
|
1791
|
+
)
|
|
1742
1792
|
if self.is_pure_stabilizer:
|
|
1743
|
-
raise RuntimeError(
|
|
1793
|
+
raise RuntimeError(
|
|
1794
|
+
"QrackStabilizer cannot hash()! (Create a QrackSimulator instead, also with isTensorNetwork=False.)"
|
|
1795
|
+
)
|
|
1744
1796
|
|
|
1745
1797
|
Qrack.qrack_lib.Hash(
|
|
1746
1798
|
self.sid, len(q), self._ulonglong_byref(q), self._to_ubyte(len(q), t)
|
|
@@ -2049,7 +2101,9 @@ class QrackSimulator:
|
|
|
2049
2101
|
RuntimeError: QrackSimulator with isTensorNetwork=True option cannot compose()! (Turn off just this option, in the constructor.)
|
|
2050
2102
|
"""
|
|
2051
2103
|
if self.is_tensor_network:
|
|
2052
|
-
raise RuntimeError(
|
|
2104
|
+
raise RuntimeError(
|
|
2105
|
+
"QrackSimulator with isTensorNetwork=True option cannot compose()! (Turn off just this option, in the constructor.)"
|
|
2106
|
+
)
|
|
2053
2107
|
|
|
2054
2108
|
Qrack.qrack_lib.Compose(self.sid, other.sid, self._ulonglong_byref(q))
|
|
2055
2109
|
self._throw_if_error()
|
|
@@ -2058,7 +2112,7 @@ class QrackSimulator:
|
|
|
2058
2112
|
"""Decompose system
|
|
2059
2113
|
|
|
2060
2114
|
Decompose the given qubit out of the system.
|
|
2061
|
-
Warning: The qubit subsystem state must be separable, or the behavior
|
|
2115
|
+
Warning: The qubit subsystem state must be separable, or the behavior
|
|
2062
2116
|
of this method is undefined.
|
|
2063
2117
|
|
|
2064
2118
|
Args:
|
|
@@ -2072,7 +2126,9 @@ class QrackSimulator:
|
|
|
2072
2126
|
State of the systems.
|
|
2073
2127
|
"""
|
|
2074
2128
|
if self.is_tensor_network:
|
|
2075
|
-
raise RuntimeError(
|
|
2129
|
+
raise RuntimeError(
|
|
2130
|
+
"QrackSimulator with isTensorNetwork=True option cannot decompose()! (Turn off just this option, in the constructor.)"
|
|
2131
|
+
)
|
|
2076
2132
|
|
|
2077
2133
|
other = QrackSimulator()
|
|
2078
2134
|
Qrack.qrack_lib.destroy(other.sid)
|
|
@@ -2086,7 +2142,7 @@ class QrackSimulator:
|
|
|
2086
2142
|
|
|
2087
2143
|
Minimally decompose a set of contiguous bits from the separably
|
|
2088
2144
|
composed unit, and discard the separable bits.
|
|
2089
|
-
Warning: The qubit subsystem state must be separable, or the behavior
|
|
2145
|
+
Warning: The qubit subsystem state must be separable, or the behavior
|
|
2090
2146
|
of this method is undefined.
|
|
2091
2147
|
|
|
2092
2148
|
Args:
|
|
@@ -2100,7 +2156,9 @@ class QrackSimulator:
|
|
|
2100
2156
|
State of the systems.
|
|
2101
2157
|
"""
|
|
2102
2158
|
if self.is_tensor_network:
|
|
2103
|
-
raise RuntimeError(
|
|
2159
|
+
raise RuntimeError(
|
|
2160
|
+
"QrackSimulator with isTensorNetwork=True option cannot dispose()! (Turn off just this option, in the constructor.)"
|
|
2161
|
+
)
|
|
2104
2162
|
|
|
2105
2163
|
l = len(q)
|
|
2106
2164
|
Qrack.qrack_lib.Dispose(self.sid, l, self._ulonglong_byref(q))
|
|
@@ -2163,8 +2221,8 @@ class QrackSimulator:
|
|
|
2163
2221
|
def in_ket(self, ket):
|
|
2164
2222
|
"""Set state vector
|
|
2165
2223
|
|
|
2166
|
-
Set state vector for the selected simulator ID.
|
|
2167
|
-
Warning: State vector is not always the internal representation leading
|
|
2224
|
+
Set state vector for the selected simulator ID.
|
|
2225
|
+
Warning: State vector is not always the internal representation leading
|
|
2168
2226
|
to sub-optimal performance of the method.
|
|
2169
2227
|
|
|
2170
2228
|
Args:
|
|
@@ -2180,7 +2238,7 @@ class QrackSimulator:
|
|
|
2180
2238
|
"""Get state vector
|
|
2181
2239
|
|
|
2182
2240
|
Returns the raw state vector of the simulator.
|
|
2183
|
-
Warning: State vector is not always the internal representation leading
|
|
2241
|
+
Warning: State vector is not always the internal representation leading
|
|
2184
2242
|
to sub-optimal performance of the method.
|
|
2185
2243
|
|
|
2186
2244
|
Raises:
|
|
@@ -2289,11 +2347,13 @@ class QrackSimulator:
|
|
|
2289
2347
|
|
|
2290
2348
|
if len(q) != len(c):
|
|
2291
2349
|
raise RuntimeError("prob_perm argument lengths do not match.")
|
|
2292
|
-
result = Qrack.qrack_lib.PermutationProb(
|
|
2350
|
+
result = Qrack.qrack_lib.PermutationProb(
|
|
2351
|
+
self.sid, len(q), self._ulonglong_byref(q), self._bool_byref(c)
|
|
2352
|
+
)
|
|
2293
2353
|
self._throw_if_error()
|
|
2294
2354
|
return result
|
|
2295
2355
|
|
|
2296
|
-
def prob_perm_rdm(self, q, c, r
|
|
2356
|
+
def prob_perm_rdm(self, q, c, r=True):
|
|
2297
2357
|
"""Probability of permutation, (tracing out the reduced
|
|
2298
2358
|
density matrix without stabilizer ancillary qubits)
|
|
2299
2359
|
|
|
@@ -2315,7 +2375,9 @@ class QrackSimulator:
|
|
|
2315
2375
|
|
|
2316
2376
|
if len(q) != len(c):
|
|
2317
2377
|
raise RuntimeError("prob_perm argument lengths do not match.")
|
|
2318
|
-
result = Qrack.qrack_lib.PermutationProbRdm(
|
|
2378
|
+
result = Qrack.qrack_lib.PermutationProbRdm(
|
|
2379
|
+
self.sid, len(q), self._ulonglong_byref(q), self._bool_byref(c), r
|
|
2380
|
+
)
|
|
2319
2381
|
self._throw_if_error()
|
|
2320
2382
|
return result
|
|
2321
2383
|
|
|
@@ -2340,7 +2402,7 @@ class QrackSimulator:
|
|
|
2340
2402
|
self._throw_if_error()
|
|
2341
2403
|
return result
|
|
2342
2404
|
|
|
2343
|
-
def permutation_expectation_rdm(self, q, r
|
|
2405
|
+
def permutation_expectation_rdm(self, q, r=True):
|
|
2344
2406
|
"""Permutation expectation value, (tracing out the reduced
|
|
2345
2407
|
density matrix without stabilizer ancillary qubits)
|
|
2346
2408
|
|
|
@@ -2389,7 +2451,7 @@ class QrackSimulator:
|
|
|
2389
2451
|
self._throw_if_error()
|
|
2390
2452
|
return result
|
|
2391
2453
|
|
|
2392
|
-
def factorized_expectation_rdm(self, q, c, r
|
|
2454
|
+
def factorized_expectation_rdm(self, q, c, r=True):
|
|
2393
2455
|
"""Factorized expectation value, (tracing out the reduced
|
|
2394
2456
|
density matrix without stabilizer ancillary qubits)
|
|
2395
2457
|
|
|
@@ -2409,7 +2471,9 @@ class QrackSimulator:
|
|
|
2409
2471
|
Expectation value
|
|
2410
2472
|
"""
|
|
2411
2473
|
if (len(q) << 1) != len(c):
|
|
2412
|
-
raise RuntimeError(
|
|
2474
|
+
raise RuntimeError(
|
|
2475
|
+
"factorized_expectation_rdm argument lengths do not match."
|
|
2476
|
+
)
|
|
2413
2477
|
m = max([(x.bit_length() + 63) // 64 for x in c])
|
|
2414
2478
|
result = Qrack.qrack_lib.FactorizedExpectationRdm(
|
|
2415
2479
|
self.sid, len(q), self._ulonglong_byref(q), m, self._to_ulonglong(m, c), r
|
|
@@ -2435,14 +2499,16 @@ class QrackSimulator:
|
|
|
2435
2499
|
Expectation value
|
|
2436
2500
|
"""
|
|
2437
2501
|
if (len(q) << 1) != len(c):
|
|
2438
|
-
raise RuntimeError(
|
|
2502
|
+
raise RuntimeError(
|
|
2503
|
+
"factorized_expectation_rdm argument lengths do not match."
|
|
2504
|
+
)
|
|
2439
2505
|
result = Qrack.qrack_lib.FactorizedExpectationFp(
|
|
2440
2506
|
self.sid, len(q), self._ulonglong_byref(q), self._real1_byref(c)
|
|
2441
2507
|
)
|
|
2442
2508
|
self._throw_if_error()
|
|
2443
2509
|
return result
|
|
2444
2510
|
|
|
2445
|
-
def factorized_expectation_fp_rdm(self, q, c, r
|
|
2511
|
+
def factorized_expectation_fp_rdm(self, q, c, r=True):
|
|
2446
2512
|
"""Factorized expectation value, (tracing out the reduced
|
|
2447
2513
|
density matrix without stabilizer ancillary qubits)
|
|
2448
2514
|
|
|
@@ -2462,7 +2528,9 @@ class QrackSimulator:
|
|
|
2462
2528
|
Expectation value
|
|
2463
2529
|
"""
|
|
2464
2530
|
if (len(q) << 1) != len(c):
|
|
2465
|
-
raise RuntimeError(
|
|
2531
|
+
raise RuntimeError(
|
|
2532
|
+
"factorized_expectation_fp_rdm argument lengths do not match."
|
|
2533
|
+
)
|
|
2466
2534
|
result = Qrack.qrack_lib.FactorizedExpectationFpRdm(
|
|
2467
2535
|
self.sid, len(q), self._ulonglong_byref(q), self._real1_byref(c), r
|
|
2468
2536
|
)
|
|
@@ -2534,11 +2602,19 @@ class QrackSimulator:
|
|
|
2534
2602
|
Expectation value
|
|
2535
2603
|
"""
|
|
2536
2604
|
if (3 * len(q)) != len(b):
|
|
2537
|
-
raise RuntimeError(
|
|
2605
|
+
raise RuntimeError(
|
|
2606
|
+
"unitary_expectation_eigenval qubit and basis argument lengths do not match."
|
|
2607
|
+
)
|
|
2538
2608
|
if (len(q) << 1) != len(e):
|
|
2539
|
-
raise RuntimeError(
|
|
2609
|
+
raise RuntimeError(
|
|
2610
|
+
"unitary_expectation_eigenval qubit and eigenvalue argument lengths do not match."
|
|
2611
|
+
)
|
|
2540
2612
|
result = Qrack.qrack_lib.UnitaryExpectationEigenVal(
|
|
2541
|
-
self.sid,
|
|
2613
|
+
self.sid,
|
|
2614
|
+
len(q),
|
|
2615
|
+
self._ulonglong_byref(q),
|
|
2616
|
+
self._real1_byref(b),
|
|
2617
|
+
self._real1_byref(e),
|
|
2542
2618
|
)
|
|
2543
2619
|
self._throw_if_error()
|
|
2544
2620
|
return result
|
|
@@ -2560,11 +2636,19 @@ class QrackSimulator:
|
|
|
2560
2636
|
Expectation value
|
|
2561
2637
|
"""
|
|
2562
2638
|
if (len(q) << 2) != len(b):
|
|
2563
|
-
raise RuntimeError(
|
|
2639
|
+
raise RuntimeError(
|
|
2640
|
+
"matrix_expectation_eigenval qubit and basis argument lengths do not match."
|
|
2641
|
+
)
|
|
2564
2642
|
if (len(q) << 1) != len(e):
|
|
2565
|
-
raise RuntimeError(
|
|
2643
|
+
raise RuntimeError(
|
|
2644
|
+
"matrix_expectation_eigenval qubit and eigenvalue argument lengths do not match."
|
|
2645
|
+
)
|
|
2566
2646
|
result = Qrack.qrack_lib.MatrixExpectationEigenVal(
|
|
2567
|
-
self.sid,
|
|
2647
|
+
self.sid,
|
|
2648
|
+
len(q),
|
|
2649
|
+
self._ulonglong_byref(q),
|
|
2650
|
+
self._complex_byref(b),
|
|
2651
|
+
self._real1_byref(e),
|
|
2568
2652
|
)
|
|
2569
2653
|
self._throw_if_error()
|
|
2570
2654
|
return result
|
|
@@ -2613,7 +2697,7 @@ class QrackSimulator:
|
|
|
2613
2697
|
self._throw_if_error()
|
|
2614
2698
|
return result
|
|
2615
2699
|
|
|
2616
|
-
def variance_rdm(self, q, r
|
|
2700
|
+
def variance_rdm(self, q, r=True):
|
|
2617
2701
|
"""Permutation variance, (tracing out the reduced
|
|
2618
2702
|
density matrix without stabilizer ancillary qubits)
|
|
2619
2703
|
|
|
@@ -2662,7 +2746,7 @@ class QrackSimulator:
|
|
|
2662
2746
|
self._throw_if_error()
|
|
2663
2747
|
return result
|
|
2664
2748
|
|
|
2665
|
-
def factorized_variance_rdm(self, q, c, r
|
|
2749
|
+
def factorized_variance_rdm(self, q, c, r=True):
|
|
2666
2750
|
"""Factorized variance, (tracing out the reduced
|
|
2667
2751
|
density matrix without stabilizer ancillary qubits)
|
|
2668
2752
|
|
|
@@ -2715,7 +2799,7 @@ class QrackSimulator:
|
|
|
2715
2799
|
self._throw_if_error()
|
|
2716
2800
|
return result
|
|
2717
2801
|
|
|
2718
|
-
def factorized_variance_fp_rdm(self, q, c, r
|
|
2802
|
+
def factorized_variance_fp_rdm(self, q, c, r=True):
|
|
2719
2803
|
"""Factorized variance, (tracing out the reduced
|
|
2720
2804
|
density matrix without stabilizer ancillary qubits)
|
|
2721
2805
|
|
|
@@ -2735,7 +2819,9 @@ class QrackSimulator:
|
|
|
2735
2819
|
variance
|
|
2736
2820
|
"""
|
|
2737
2821
|
if (len(q) << 1) != len(c):
|
|
2738
|
-
raise RuntimeError(
|
|
2822
|
+
raise RuntimeError(
|
|
2823
|
+
"factorized_variance_fp_rdm argument lengths do not match."
|
|
2824
|
+
)
|
|
2739
2825
|
result = Qrack.qrack_lib.FactorizedVarianceFpRdm(
|
|
2740
2826
|
self.sid, len(q), self._ulonglong_byref(q), self._real1_byref(c), r
|
|
2741
2827
|
)
|
|
@@ -2807,11 +2893,19 @@ class QrackSimulator:
|
|
|
2807
2893
|
variance
|
|
2808
2894
|
"""
|
|
2809
2895
|
if (3 * len(q)) != len(b):
|
|
2810
|
-
raise RuntimeError(
|
|
2896
|
+
raise RuntimeError(
|
|
2897
|
+
"unitary_variance_eigenval qubit and basis argument lengths do not match."
|
|
2898
|
+
)
|
|
2811
2899
|
if (len(q) << 1) != len(e):
|
|
2812
|
-
raise RuntimeError(
|
|
2900
|
+
raise RuntimeError(
|
|
2901
|
+
"unitary_variance_eigenval qubit and eigenvalue argument lengths do not match."
|
|
2902
|
+
)
|
|
2813
2903
|
result = Qrack.qrack_lib.UnitaryVarianceEigenVal(
|
|
2814
|
-
self.sid,
|
|
2904
|
+
self.sid,
|
|
2905
|
+
len(q),
|
|
2906
|
+
self._ulonglong_byref(q),
|
|
2907
|
+
self._real1_byref(b),
|
|
2908
|
+
self._real1_byref(e),
|
|
2815
2909
|
)
|
|
2816
2910
|
self._throw_if_error()
|
|
2817
2911
|
return result
|
|
@@ -2833,11 +2927,19 @@ class QrackSimulator:
|
|
|
2833
2927
|
variance
|
|
2834
2928
|
"""
|
|
2835
2929
|
if (len(q) << 2) != len(b):
|
|
2836
|
-
raise RuntimeError(
|
|
2930
|
+
raise RuntimeError(
|
|
2931
|
+
"matrix_variance_eigenval qubit and basis argument lengths do not match."
|
|
2932
|
+
)
|
|
2837
2933
|
if (len(q) << 1) != len(e):
|
|
2838
|
-
raise RuntimeError(
|
|
2934
|
+
raise RuntimeError(
|
|
2935
|
+
"matrix_variance_eigenval qubit and eigenvalue argument lengths do not match."
|
|
2936
|
+
)
|
|
2839
2937
|
result = Qrack.qrack_lib.MatrixVarianceEigenVal(
|
|
2840
|
-
self.sid,
|
|
2938
|
+
self.sid,
|
|
2939
|
+
len(q),
|
|
2940
|
+
self._ulonglong_byref(q),
|
|
2941
|
+
self._complex_byref(b),
|
|
2942
|
+
self._real1_byref(e),
|
|
2841
2943
|
)
|
|
2842
2944
|
self._throw_if_error()
|
|
2843
2945
|
return result
|
|
@@ -2906,9 +3008,13 @@ class QrackSimulator:
|
|
|
2906
3008
|
RuntimeError: QrackSimulator with isTensorNetwork=True option cannot phase_parity()! (Turn off just this option, in the constructor.)
|
|
2907
3009
|
"""
|
|
2908
3010
|
if self.is_tensor_network:
|
|
2909
|
-
raise RuntimeError(
|
|
3011
|
+
raise RuntimeError(
|
|
3012
|
+
"QrackSimulator with isTensorNetwork=True option cannot phase_parity()! (Turn off just this option, in the constructor.)"
|
|
3013
|
+
)
|
|
2910
3014
|
if self.is_pure_stabilizer:
|
|
2911
|
-
raise RuntimeError(
|
|
3015
|
+
raise RuntimeError(
|
|
3016
|
+
"QrackStabilizer cannot phase_parity()! (Create a QrackSimulator instead, also with isTensorNetwork=False.)"
|
|
3017
|
+
)
|
|
2912
3018
|
|
|
2913
3019
|
Qrack.qrack_lib.PhaseParity(
|
|
2914
3020
|
self.sid, ctypes.c_double(la), len(q), self._ulonglong_byref(q)
|
|
@@ -2929,13 +3035,15 @@ class QrackSimulator:
|
|
|
2929
3035
|
RuntimeError: QrackSimulator with isTensorNetwork=True option cannot phase_root_n()! (Turn off just this option, in the constructor.)
|
|
2930
3036
|
"""
|
|
2931
3037
|
if self.is_tensor_network:
|
|
2932
|
-
raise RuntimeError(
|
|
3038
|
+
raise RuntimeError(
|
|
3039
|
+
"QrackSimulator with isTensorNetwork=True option cannot phase_root_n()! (Turn off just this option, in the constructor.)"
|
|
3040
|
+
)
|
|
2933
3041
|
if self.is_pure_stabilizer:
|
|
2934
|
-
raise RuntimeError(
|
|
3042
|
+
raise RuntimeError(
|
|
3043
|
+
"QrackStabilizer cannot phase_root_n()! (Create a QrackSimulator instead, also with isTensorNetwork=False.)"
|
|
3044
|
+
)
|
|
2935
3045
|
|
|
2936
|
-
Qrack.qrack_lib.PhaseRootN(
|
|
2937
|
-
self.sid, n, len(q), self._ulonglong_byref(q)
|
|
2938
|
-
)
|
|
3046
|
+
Qrack.qrack_lib.PhaseRootN(self.sid, n, len(q), self._ulonglong_byref(q))
|
|
2939
3047
|
self._throw_if_error()
|
|
2940
3048
|
|
|
2941
3049
|
def try_separate_1qb(self, qi1):
|
|
@@ -3008,12 +3116,9 @@ class QrackSimulator:
|
|
|
3008
3116
|
Raises:
|
|
3009
3117
|
Runtimeerror: QrackSimulator raised an exception.
|
|
3010
3118
|
"""
|
|
3011
|
-
result = Qrack.qrack_lib.Separate(
|
|
3012
|
-
self.sid, len(qs), self._ulonglong_byref(qs)
|
|
3013
|
-
)
|
|
3119
|
+
result = Qrack.qrack_lib.Separate(self.sid, len(qs), self._ulonglong_byref(qs))
|
|
3014
3120
|
self._throw_if_error()
|
|
3015
3121
|
|
|
3016
|
-
|
|
3017
3122
|
def get_unitary_fidelity(self):
|
|
3018
3123
|
"""Get fidelity estimate
|
|
3019
3124
|
|
|
@@ -3157,10 +3262,18 @@ class QrackSimulator:
|
|
|
3157
3262
|
Args:
|
|
3158
3263
|
filename: Name of file
|
|
3159
3264
|
"""
|
|
3160
|
-
Qrack.qrack_lib.qstabilizer_out_to_file(self.sid, filename.encode(
|
|
3265
|
+
Qrack.qrack_lib.qstabilizer_out_to_file(self.sid, filename.encode("utf-8"))
|
|
3161
3266
|
self._throw_if_error()
|
|
3162
3267
|
|
|
3163
|
-
def in_from_file(
|
|
3268
|
+
def in_from_file(
|
|
3269
|
+
filename,
|
|
3270
|
+
is_binary_decision_tree=False,
|
|
3271
|
+
is_paged=True,
|
|
3272
|
+
is_cpu_gpu_hybrid=False,
|
|
3273
|
+
is_opencl=True,
|
|
3274
|
+
is_host_pointer=False,
|
|
3275
|
+
is_noisy=False,
|
|
3276
|
+
):
|
|
3164
3277
|
"""Input state from file (stabilizer only!)
|
|
3165
3278
|
|
|
3166
3279
|
Reads in a hybrid stabilizer state from file.
|
|
@@ -3182,9 +3295,9 @@ class QrackSimulator:
|
|
|
3182
3295
|
isCpuGpuHybrid=is_cpu_gpu_hybrid,
|
|
3183
3296
|
isOpenCL=is_opencl,
|
|
3184
3297
|
isHostPointer=is_host_pointer,
|
|
3185
|
-
isNoisy=is_noisy
|
|
3298
|
+
isNoisy=is_noisy,
|
|
3186
3299
|
)
|
|
3187
|
-
Qrack.qrack_lib.qstabilizer_in_from_file(out.sid, filename.encode(
|
|
3300
|
+
Qrack.qrack_lib.qstabilizer_in_from_file(out.sid, filename.encode("utf-8"))
|
|
3188
3301
|
out._throw_if_error()
|
|
3189
3302
|
|
|
3190
3303
|
return out
|
|
@@ -3209,7 +3322,7 @@ class QrackSimulator:
|
|
|
3209
3322
|
)
|
|
3210
3323
|
|
|
3211
3324
|
lines = []
|
|
3212
|
-
with open(filename,
|
|
3325
|
+
with open(filename, "r") as file:
|
|
3213
3326
|
lines = file.readlines()
|
|
3214
3327
|
|
|
3215
3328
|
logical_qubits = int(lines[0])
|
|
@@ -3232,7 +3345,7 @@ class QrackSimulator:
|
|
|
3232
3345
|
line_number += 1
|
|
3233
3346
|
tableau = []
|
|
3234
3347
|
row_count = shard_map_size << 1
|
|
3235
|
-
for line in lines[line_number:(line_number + row_count)]:
|
|
3348
|
+
for line in lines[line_number : (line_number + row_count)]:
|
|
3236
3349
|
bits = line.split()
|
|
3237
3350
|
if len(bits) != (row_count + 1):
|
|
3238
3351
|
raise QrackException("Invalid Qrack hybrid stabilizer file!")
|
|
@@ -3241,7 +3354,7 @@ class QrackSimulator:
|
|
|
3241
3354
|
row.append(bool(int(bits[b])))
|
|
3242
3355
|
row.append(bool((int(bits[-1]) >> 1) & 1))
|
|
3243
3356
|
tableau.append(row)
|
|
3244
|
-
line_number +=
|
|
3357
|
+
line_number += shard_map_size << 1
|
|
3245
3358
|
tableau = np.array(tableau, bool)
|
|
3246
3359
|
|
|
3247
3360
|
clifford = Clifford(tableau, validate=False, copy=False)
|
|
@@ -3253,11 +3366,11 @@ class QrackSimulator:
|
|
|
3253
3366
|
for line in lines[line_number:]:
|
|
3254
3367
|
i = 0
|
|
3255
3368
|
tokens = line.split()
|
|
3256
|
-
op = np.zeros((2,2), dtype=complex)
|
|
3369
|
+
op = np.zeros((2, 2), dtype=complex)
|
|
3257
3370
|
row = []
|
|
3258
3371
|
for _ in range(2):
|
|
3259
|
-
amp = tokens[i].replace("(","").replace(")","").split(
|
|
3260
|
-
row.append(float(amp[0]) + float(amp[1])*1j)
|
|
3372
|
+
amp = tokens[i].replace("(", "").replace(")", "").split(",")
|
|
3373
|
+
row.append(float(amp[0]) + float(amp[1]) * 1j)
|
|
3261
3374
|
i = i + 1
|
|
3262
3375
|
l = math.sqrt(np.real(row[0] * np.conj(row[0]) + row[1] * np.conj(row[1])))
|
|
3263
3376
|
op[0][0] = row[0] / l
|
|
@@ -3270,8 +3383,8 @@ class QrackSimulator:
|
|
|
3270
3383
|
|
|
3271
3384
|
row = []
|
|
3272
3385
|
for _ in range(2):
|
|
3273
|
-
amp = tokens[i].replace("(","").replace(")","").split(
|
|
3274
|
-
row.append(float(amp[0]) + float(amp[1])*1j)
|
|
3386
|
+
amp = tokens[i].replace("(", "").replace(")", "").split(",")
|
|
3387
|
+
row.append(float(amp[0]) + float(amp[1]) * 1j)
|
|
3275
3388
|
i = i + 1
|
|
3276
3389
|
l = math.sqrt(np.real(row[0] * np.conj(row[0]) + row[1] * np.conj(row[1])))
|
|
3277
3390
|
op[1][0] = row[0] / l
|
|
@@ -3290,9 +3403,27 @@ class QrackSimulator:
|
|
|
3290
3403
|
non_clifford_gates.append(op)
|
|
3291
3404
|
g = g + 1
|
|
3292
3405
|
|
|
3293
|
-
basis_gates = [
|
|
3406
|
+
basis_gates = [
|
|
3407
|
+
"rz",
|
|
3408
|
+
"h",
|
|
3409
|
+
"x",
|
|
3410
|
+
"y",
|
|
3411
|
+
"z",
|
|
3412
|
+
"sx",
|
|
3413
|
+
"sxdg",
|
|
3414
|
+
"s",
|
|
3415
|
+
"sdg",
|
|
3416
|
+
"t",
|
|
3417
|
+
"tdg",
|
|
3418
|
+
"cx",
|
|
3419
|
+
"cy",
|
|
3420
|
+
"cz",
|
|
3421
|
+
"swap",
|
|
3422
|
+
]
|
|
3294
3423
|
try:
|
|
3295
|
-
circ = transpile(
|
|
3424
|
+
circ = transpile(
|
|
3425
|
+
clifford_circ, basis_gates=basis_gates, optimization_level=2
|
|
3426
|
+
)
|
|
3296
3427
|
except:
|
|
3297
3428
|
circ = clifford_circ
|
|
3298
3429
|
|
|
@@ -3311,16 +3442,16 @@ class QrackSimulator:
|
|
|
3311
3442
|
"""
|
|
3312
3443
|
Reorders qubits in the circuit according to the given mapping using SWAP gates.
|
|
3313
3444
|
(Thanks to "Elara," an OpenAI GPT, for this implementation)
|
|
3314
|
-
|
|
3445
|
+
|
|
3315
3446
|
Parameters:
|
|
3316
3447
|
- circuit (QuantumCircuit): The circuit to modify.
|
|
3317
3448
|
- mapping (dict): Dictionary mapping internal qubit indices to logical qubit indices.
|
|
3318
|
-
|
|
3449
|
+
|
|
3319
3450
|
Returns:
|
|
3320
3451
|
- QuantumCircuit: The modified circuit with qubits reordered.
|
|
3321
3452
|
"""
|
|
3322
3453
|
swaps = []
|
|
3323
|
-
|
|
3454
|
+
|
|
3324
3455
|
# Determine swaps to fix the order
|
|
3325
3456
|
for logical_index in sorted(mapping):
|
|
3326
3457
|
internal_index = mapping[logical_index]
|
|
@@ -3329,11 +3460,11 @@ class QrackSimulator:
|
|
|
3329
3460
|
# Update the reverse mapping for subsequent swaps
|
|
3330
3461
|
mapping[logical_index] = logical_index
|
|
3331
3462
|
mapping[internal_index] = internal_index
|
|
3332
|
-
|
|
3463
|
+
|
|
3333
3464
|
# Apply the swaps to the circuit
|
|
3334
3465
|
for qubit1, qubit2 in swaps:
|
|
3335
3466
|
circuit.swap(qubit1, qubit2)
|
|
3336
|
-
|
|
3467
|
+
|
|
3337
3468
|
return circuit
|
|
3338
3469
|
|
|
3339
3470
|
def file_to_optimized_qiskit_circuit(filename):
|
|
@@ -3353,7 +3484,7 @@ class QrackSimulator:
|
|
|
3353
3484
|
QrackCircuit, you must install Qiskit, numpy, and math!
|
|
3354
3485
|
"""
|
|
3355
3486
|
circ = QrackSimulator.file_to_qiskit_circuit(filename)
|
|
3356
|
-
|
|
3487
|
+
|
|
3357
3488
|
width = 0
|
|
3358
3489
|
with open(filename, "r", encoding="utf-8") as file:
|
|
3359
3490
|
width = int(file.readline())
|
|
@@ -3373,40 +3504,104 @@ class QrackSimulator:
|
|
|
3373
3504
|
op = circ.data[j].operation
|
|
3374
3505
|
qubits = circ.data[j].qubits
|
|
3375
3506
|
if len(qubits) > 2:
|
|
3376
|
-
raise RuntimeError(
|
|
3507
|
+
raise RuntimeError(
|
|
3508
|
+
"Something went wrong while optimizing circuit! (Found a gate with 3 or more qubits)"
|
|
3509
|
+
)
|
|
3377
3510
|
q1 = circ.find_bit(qubits[0])[0]
|
|
3378
3511
|
if (len(qubits) < 2) and (q1 == i):
|
|
3379
3512
|
if op.name == "unitary":
|
|
3380
3513
|
non_clifford = np.matmul(op.params[0], non_clifford)
|
|
3381
3514
|
elif op.name == "rz":
|
|
3382
3515
|
lm = float(op.params[0])
|
|
3383
|
-
non_clifford = np.matmul(
|
|
3516
|
+
non_clifford = np.matmul(
|
|
3517
|
+
[[np.exp(-1j * lm / 2), 0], [0, np.exp(1j * lm / 2)]],
|
|
3518
|
+
non_clifford,
|
|
3519
|
+
)
|
|
3384
3520
|
elif op.name == "h":
|
|
3385
|
-
non_clifford = np.matmul(
|
|
3521
|
+
non_clifford = np.matmul(
|
|
3522
|
+
np.array(
|
|
3523
|
+
[[sqrt1_2, sqrt1_2], [sqrt1_2, -sqrt1_2]], np.complex128
|
|
3524
|
+
),
|
|
3525
|
+
non_clifford,
|
|
3526
|
+
)
|
|
3386
3527
|
elif op.name == "x":
|
|
3387
|
-
non_clifford = np.matmul(
|
|
3528
|
+
non_clifford = np.matmul(
|
|
3529
|
+
np.array([[0, 1], [1, 0]], np.complex128), non_clifford
|
|
3530
|
+
)
|
|
3388
3531
|
elif op.name == "y":
|
|
3389
|
-
non_clifford = np.matmul(
|
|
3532
|
+
non_clifford = np.matmul(
|
|
3533
|
+
np.array([[0, -1j], [1j, 0]], np.complex128), non_clifford
|
|
3534
|
+
)
|
|
3390
3535
|
elif op.name == "z":
|
|
3391
|
-
non_clifford = np.matmul(
|
|
3536
|
+
non_clifford = np.matmul(
|
|
3537
|
+
np.array([[1, 0], [0, -1]], np.complex128), non_clifford
|
|
3538
|
+
)
|
|
3392
3539
|
elif op.name == "sx":
|
|
3393
|
-
non_clifford = np.matmul(
|
|
3540
|
+
non_clifford = np.matmul(
|
|
3541
|
+
np.array(
|
|
3542
|
+
[
|
|
3543
|
+
[(1 + 1j) / 2, (1 - 1j) / 2],
|
|
3544
|
+
[(1 - 1j) / 2, (1 + 1j) / 2],
|
|
3545
|
+
],
|
|
3546
|
+
np.complex128,
|
|
3547
|
+
),
|
|
3548
|
+
non_clifford,
|
|
3549
|
+
)
|
|
3394
3550
|
elif op.name == "sxdg":
|
|
3395
|
-
non_clifford = np.matmul(
|
|
3551
|
+
non_clifford = np.matmul(
|
|
3552
|
+
np.array(
|
|
3553
|
+
[
|
|
3554
|
+
[(1 - 1j) / 2, (1 + 1j) / 2],
|
|
3555
|
+
[(1 + 1j) / 2, (1 - 1j) / 2],
|
|
3556
|
+
],
|
|
3557
|
+
np.complex128,
|
|
3558
|
+
),
|
|
3559
|
+
non_clifford,
|
|
3560
|
+
)
|
|
3396
3561
|
elif op.name == "sy":
|
|
3397
|
-
non_clifford = np.matmul(
|
|
3562
|
+
non_clifford = np.matmul(
|
|
3563
|
+
np.array(
|
|
3564
|
+
[
|
|
3565
|
+
[(1 + 1j) / 2, -(1 + 1j) / 2],
|
|
3566
|
+
[(1 + 1j) / 2, (1 + 1j) / 2],
|
|
3567
|
+
],
|
|
3568
|
+
np.complex128,
|
|
3569
|
+
),
|
|
3570
|
+
non_clifford,
|
|
3571
|
+
)
|
|
3398
3572
|
elif op.name == "sydg":
|
|
3399
|
-
non_clifford = np.matmul(
|
|
3573
|
+
non_clifford = np.matmul(
|
|
3574
|
+
np.array(
|
|
3575
|
+
[
|
|
3576
|
+
[(1 - 1j) / 2, (1 - 1j) / 2],
|
|
3577
|
+
[(-1 + 1j) / 2, (1 - 1j) / 2],
|
|
3578
|
+
],
|
|
3579
|
+
np.complex128,
|
|
3580
|
+
),
|
|
3581
|
+
non_clifford,
|
|
3582
|
+
)
|
|
3400
3583
|
elif op.name == "s":
|
|
3401
|
-
non_clifford = np.matmul(
|
|
3584
|
+
non_clifford = np.matmul(
|
|
3585
|
+
np.array([[1, 0], [0, 1j]], np.complex128), non_clifford
|
|
3586
|
+
)
|
|
3402
3587
|
elif op.name == "sdg":
|
|
3403
|
-
non_clifford = np.matmul(
|
|
3588
|
+
non_clifford = np.matmul(
|
|
3589
|
+
np.array([[1, 0], [0, -1j]], np.complex128), non_clifford
|
|
3590
|
+
)
|
|
3404
3591
|
elif op.name == "t":
|
|
3405
|
-
non_clifford = np.matmul(
|
|
3592
|
+
non_clifford = np.matmul(
|
|
3593
|
+
np.array([[1, 0], [0, sqrt_pi]], np.complex128),
|
|
3594
|
+
non_clifford,
|
|
3595
|
+
)
|
|
3406
3596
|
elif op.name == "tdg":
|
|
3407
|
-
non_clifford = np.matmul(
|
|
3597
|
+
non_clifford = np.matmul(
|
|
3598
|
+
np.array([[1, 0], [0, sqrt_ni]], np.complex128),
|
|
3599
|
+
non_clifford,
|
|
3600
|
+
)
|
|
3408
3601
|
else:
|
|
3409
|
-
raise RuntimeError(
|
|
3602
|
+
raise RuntimeError(
|
|
3603
|
+
"Something went wrong while optimizing circuit! (Dropped a single-qubit gate.)"
|
|
3604
|
+
)
|
|
3410
3605
|
|
|
3411
3606
|
del circ.data[j]
|
|
3412
3607
|
continue
|
|
@@ -3422,7 +3617,7 @@ class QrackSimulator:
|
|
|
3422
3617
|
continue
|
|
3423
3618
|
|
|
3424
3619
|
if op.name == "swap":
|
|
3425
|
-
i =
|
|
3620
|
+
i = q2 if i == q1 else q1
|
|
3426
3621
|
|
|
3427
3622
|
if circ.data[j] in passed_swaps:
|
|
3428
3623
|
passed_swaps.remove(circ.data[j])
|
|
@@ -3432,15 +3627,21 @@ class QrackSimulator:
|
|
|
3432
3627
|
passed_swaps.append(circ.data[j])
|
|
3433
3628
|
|
|
3434
3629
|
j += 1
|
|
3435
|
-
continue
|
|
3630
|
+
continue
|
|
3436
3631
|
|
|
3437
|
-
if (q1 == i) and (
|
|
3438
|
-
|
|
3632
|
+
if (q1 == i) and (
|
|
3633
|
+
(op.name == "cx") or (op.name == "cy") or (op.name == "cz")
|
|
3634
|
+
):
|
|
3635
|
+
if np.isclose(np.abs(non_clifford[0][1]), 0) and np.isclose(
|
|
3636
|
+
np.abs(non_clifford[1][0]), 0
|
|
3637
|
+
):
|
|
3439
3638
|
# If we're not buffering anything but phase, the blocking gate has no effect, and we're safe to continue.
|
|
3440
3639
|
del circ.data[j]
|
|
3441
3640
|
continue
|
|
3442
3641
|
|
|
3443
|
-
if
|
|
3642
|
+
if np.isclose(np.abs(non_clifford[0][0]), 0) and np.isclose(
|
|
3643
|
+
np.abs(non_clifford[1][1]), 0
|
|
3644
|
+
):
|
|
3444
3645
|
# If we're buffering full negation (plus phase), the control qubit can be dropped.
|
|
3445
3646
|
c = QuantumCircuit(circ.qubits)
|
|
3446
3647
|
if op.name == "cx":
|
|
@@ -3480,40 +3681,104 @@ class QrackSimulator:
|
|
|
3480
3681
|
op = circ.data[j].operation
|
|
3481
3682
|
qubits = circ.data[j].qubits
|
|
3482
3683
|
if len(qubits) > 2:
|
|
3483
|
-
raise RuntimeError(
|
|
3684
|
+
raise RuntimeError(
|
|
3685
|
+
"Something went wrong while optimizing circuit! (Found a gate with 3 or more qubits.)"
|
|
3686
|
+
)
|
|
3484
3687
|
q1 = circ.find_bit(qubits[0])[0]
|
|
3485
3688
|
if (len(qubits) < 2) and (q1 == i):
|
|
3486
3689
|
if op.name == "unitary":
|
|
3487
3690
|
non_clifford = np.matmul(non_clifford, op.params[0])
|
|
3488
3691
|
elif op.name == "rz":
|
|
3489
3692
|
lm = float(op.params[0])
|
|
3490
|
-
non_clifford = np.matmul(
|
|
3693
|
+
non_clifford = np.matmul(
|
|
3694
|
+
non_clifford,
|
|
3695
|
+
[[np.exp(-1j * lm / 2), 0], [0, np.exp(1j * lm / 2)]],
|
|
3696
|
+
)
|
|
3491
3697
|
elif op.name == "h":
|
|
3492
|
-
non_clifford = np.matmul(
|
|
3698
|
+
non_clifford = np.matmul(
|
|
3699
|
+
non_clifford,
|
|
3700
|
+
np.array(
|
|
3701
|
+
[[sqrt1_2, sqrt1_2], [sqrt1_2, -sqrt1_2]], np.complex128
|
|
3702
|
+
),
|
|
3703
|
+
)
|
|
3493
3704
|
elif op.name == "x":
|
|
3494
|
-
non_clifford = np.matmul(
|
|
3705
|
+
non_clifford = np.matmul(
|
|
3706
|
+
non_clifford, np.array([[0, 1], [1, 0]], np.complex128)
|
|
3707
|
+
)
|
|
3495
3708
|
elif op.name == "y":
|
|
3496
|
-
non_clifford = np.matmul(
|
|
3709
|
+
non_clifford = np.matmul(
|
|
3710
|
+
non_clifford, np.array([[0, -1j], [1j, 0]], np.complex128)
|
|
3711
|
+
)
|
|
3497
3712
|
elif op.name == "z":
|
|
3498
|
-
non_clifford = np.matmul(
|
|
3713
|
+
non_clifford = np.matmul(
|
|
3714
|
+
non_clifford, np.array([[1, 0], [0, -1]], np.complex128)
|
|
3715
|
+
)
|
|
3499
3716
|
elif op.name == "sx":
|
|
3500
|
-
non_clifford = np.matmul(
|
|
3717
|
+
non_clifford = np.matmul(
|
|
3718
|
+
non_clifford,
|
|
3719
|
+
np.array(
|
|
3720
|
+
[
|
|
3721
|
+
[(1 + 1j) / 2, (1 - 1j) / 2],
|
|
3722
|
+
[(1 - 1j) / 2, (1 + 1j) / 2],
|
|
3723
|
+
],
|
|
3724
|
+
np.complex128,
|
|
3725
|
+
),
|
|
3726
|
+
)
|
|
3501
3727
|
elif op.name == "sxdg":
|
|
3502
|
-
non_clifford = np.matmul(
|
|
3728
|
+
non_clifford = np.matmul(
|
|
3729
|
+
non_clifford,
|
|
3730
|
+
np.array(
|
|
3731
|
+
[
|
|
3732
|
+
[(1 - 1j) / 2, (1 + 1j) / 2],
|
|
3733
|
+
[(1 + 1j) / 2, (1 - 1j) / 2],
|
|
3734
|
+
],
|
|
3735
|
+
np.complex128,
|
|
3736
|
+
),
|
|
3737
|
+
)
|
|
3503
3738
|
elif op.name == "sy":
|
|
3504
|
-
non_clifford = np.matmul(
|
|
3739
|
+
non_clifford = np.matmul(
|
|
3740
|
+
non_clifford,
|
|
3741
|
+
np.array(
|
|
3742
|
+
[
|
|
3743
|
+
[(1 + 1j) / 2, -(1 + 1j) / 2],
|
|
3744
|
+
[(1 + 1j) / 2, (1 + 1j) / 2],
|
|
3745
|
+
],
|
|
3746
|
+
np.complex128,
|
|
3747
|
+
),
|
|
3748
|
+
)
|
|
3505
3749
|
elif op.name == "sydg":
|
|
3506
|
-
non_clifford = np.matmul(
|
|
3750
|
+
non_clifford = np.matmul(
|
|
3751
|
+
non_clifford,
|
|
3752
|
+
np.array(
|
|
3753
|
+
[
|
|
3754
|
+
[(1 - 1j) / 2, (1 - 1j) / 2],
|
|
3755
|
+
[(-1 + 1j) / 2, (1 - 1j) / 2],
|
|
3756
|
+
],
|
|
3757
|
+
np.complex128,
|
|
3758
|
+
),
|
|
3759
|
+
)
|
|
3507
3760
|
elif op.name == "s":
|
|
3508
|
-
non_clifford = np.matmul(
|
|
3761
|
+
non_clifford = np.matmul(
|
|
3762
|
+
non_clifford, np.array([[1, 0], [0, 1j]], np.complex128)
|
|
3763
|
+
)
|
|
3509
3764
|
elif op.name == "sdg":
|
|
3510
|
-
non_clifford = np.matmul(
|
|
3765
|
+
non_clifford = np.matmul(
|
|
3766
|
+
non_clifford, np.array([[1, 0], [0, -1j]], np.complex128)
|
|
3767
|
+
)
|
|
3511
3768
|
elif op.name == "t":
|
|
3512
|
-
non_clifford = np.matmul(
|
|
3769
|
+
non_clifford = np.matmul(
|
|
3770
|
+
non_clifford,
|
|
3771
|
+
np.array([[1, 0], [0, sqrt_pi]], np.complex128),
|
|
3772
|
+
)
|
|
3513
3773
|
elif op.name == "tdg":
|
|
3514
|
-
non_clifford = np.matmul(
|
|
3774
|
+
non_clifford = np.matmul(
|
|
3775
|
+
non_clifford,
|
|
3776
|
+
np.array([[1, 0], [0, sqrt_ni]], np.complex128),
|
|
3777
|
+
)
|
|
3515
3778
|
else:
|
|
3516
|
-
raise RuntimeError(
|
|
3779
|
+
raise RuntimeError(
|
|
3780
|
+
"Something went wrong while optimizing circuit! (Dropped a single-qubit gate.)"
|
|
3781
|
+
)
|
|
3517
3782
|
|
|
3518
3783
|
del circ.data[j]
|
|
3519
3784
|
j -= 1
|
|
@@ -3530,7 +3795,7 @@ class QrackSimulator:
|
|
|
3530
3795
|
continue
|
|
3531
3796
|
|
|
3532
3797
|
if (op.name == "swap") and (q1 >= width) and (q2 >= width):
|
|
3533
|
-
i =
|
|
3798
|
+
i = q2 if i == q1 else q1
|
|
3534
3799
|
if circ.data[j] in passed_swaps:
|
|
3535
3800
|
passed_swaps.remove(circ.data[j])
|
|
3536
3801
|
del circ.data[j]
|
|
@@ -3540,7 +3805,14 @@ class QrackSimulator:
|
|
|
3540
3805
|
j -= 1
|
|
3541
3806
|
continue
|
|
3542
3807
|
|
|
3543
|
-
if (
|
|
3808
|
+
if (
|
|
3809
|
+
(q1 == i)
|
|
3810
|
+
and ((op.name == "cx") or (op.name == "cy") or (op.name == "cz"))
|
|
3811
|
+
and (
|
|
3812
|
+
np.isclose(np.abs(non_clifford[0][1]), 0)
|
|
3813
|
+
and np.isclose(np.abs(non_clifford[1][0]), 0)
|
|
3814
|
+
)
|
|
3815
|
+
):
|
|
3544
3816
|
# If we're not buffering anything but phase, this commutes with control, and we're safe to continue.
|
|
3545
3817
|
j -= 1
|
|
3546
3818
|
continue
|
|
@@ -3578,7 +3850,9 @@ class QrackSimulator:
|
|
|
3578
3850
|
break
|
|
3579
3851
|
|
|
3580
3852
|
# Re-injection branch (apply gadget to target)
|
|
3581
|
-
to_inject = np.matmul(
|
|
3853
|
+
to_inject = np.matmul(
|
|
3854
|
+
non_clifford, np.array([[sqrt1_2, sqrt1_2], [sqrt1_2, -sqrt1_2]])
|
|
3855
|
+
)
|
|
3582
3856
|
if np.allclose(to_inject, ident):
|
|
3583
3857
|
# No buffer content to write to circuit definition
|
|
3584
3858
|
del circ.data[j]
|
|
@@ -3590,18 +3864,41 @@ class QrackSimulator:
|
|
|
3590
3864
|
circ.data.insert(j, copy.deepcopy(c.data[0]))
|
|
3591
3865
|
j -= 1
|
|
3592
3866
|
|
|
3593
|
-
basis_gates=[
|
|
3867
|
+
basis_gates = [
|
|
3868
|
+
"u",
|
|
3869
|
+
"rz",
|
|
3870
|
+
"h",
|
|
3871
|
+
"x",
|
|
3872
|
+
"y",
|
|
3873
|
+
"z",
|
|
3874
|
+
"sx",
|
|
3875
|
+
"sxdg",
|
|
3876
|
+
"s",
|
|
3877
|
+
"sdg",
|
|
3878
|
+
"t",
|
|
3879
|
+
"tdg",
|
|
3880
|
+
"cx",
|
|
3881
|
+
"cy",
|
|
3882
|
+
"cz",
|
|
3883
|
+
"swap",
|
|
3884
|
+
]
|
|
3594
3885
|
circ = transpile(circ, basis_gates=basis_gates, optimization_level=2)
|
|
3595
3886
|
|
|
3596
|
-
#Eliminate unused ancillae
|
|
3887
|
+
# Eliminate unused ancillae
|
|
3597
3888
|
try:
|
|
3598
3889
|
qasm = qasm3.dumps(circ)
|
|
3599
3890
|
except:
|
|
3600
3891
|
qasm = circ.qasm()
|
|
3601
|
-
qasm = qasm.replace(
|
|
3602
|
-
|
|
3892
|
+
qasm = qasm.replace(
|
|
3893
|
+
"qreg q[" + str(circ.width()) + "];", "qreg q[" + str(width) + "];"
|
|
3894
|
+
)
|
|
3895
|
+
highest_index = max(
|
|
3896
|
+
[int(x) for x in re.findall(r"\[(.*?)\]", qasm) if x.isdigit()]
|
|
3897
|
+
)
|
|
3603
3898
|
if highest_index != width:
|
|
3604
|
-
qasm = qasm.replace(
|
|
3899
|
+
qasm = qasm.replace(
|
|
3900
|
+
"qreg q[" + str(width) + "];", "qreg q[" + str(highest_index) + "];"
|
|
3901
|
+
)
|
|
3605
3902
|
|
|
3606
3903
|
orig_circ = circ
|
|
3607
3904
|
try:
|
|
@@ -3667,11 +3964,11 @@ class QrackSimulator:
|
|
|
3667
3964
|
def _apply_op(self, operation):
|
|
3668
3965
|
name = operation.name
|
|
3669
3966
|
|
|
3670
|
-
if (name ==
|
|
3967
|
+
if (name == "id") or (name == "barrier"):
|
|
3671
3968
|
# Skip measurement logic
|
|
3672
3969
|
return
|
|
3673
3970
|
|
|
3674
|
-
conditional = getattr(operation,
|
|
3971
|
+
conditional = getattr(operation, "conditional", None)
|
|
3675
3972
|
if isinstance(conditional, int):
|
|
3676
3973
|
conditional_bit_set = (self._classical_register >> conditional) & 1
|
|
3677
3974
|
if not conditional_bit_set:
|
|
@@ -3686,68 +3983,78 @@ class QrackSimulator:
|
|
|
3686
3983
|
if value != int(conditional.val, 16):
|
|
3687
3984
|
return
|
|
3688
3985
|
|
|
3689
|
-
if (name ==
|
|
3986
|
+
if (name == "u1") or (name == "p"):
|
|
3690
3987
|
self._sim.u(operation.qubits[0]._index, 0, 0, float(operation.params[0]))
|
|
3691
|
-
elif name ==
|
|
3988
|
+
elif name == "u2":
|
|
3692
3989
|
self._sim.u(
|
|
3693
3990
|
operation.qubits[0]._index,
|
|
3694
3991
|
math.pi / 2,
|
|
3695
3992
|
float(operation.params[0]),
|
|
3696
3993
|
float(operation.params[1]),
|
|
3697
3994
|
)
|
|
3698
|
-
elif (name ==
|
|
3995
|
+
elif (name == "u3") or (name == "u"):
|
|
3699
3996
|
self._sim.u(
|
|
3700
3997
|
operation.qubits[0]._index,
|
|
3701
3998
|
float(operation.params[0]),
|
|
3702
3999
|
float(operation.params[1]),
|
|
3703
4000
|
float(operation.params[2]),
|
|
3704
4001
|
)
|
|
3705
|
-
elif (name ==
|
|
4002
|
+
elif (name == "unitary") and (len(operation.qubits) == 1):
|
|
3706
4003
|
self._sim.mtrx(operation.params[0].flatten(), operation.qubits[0]._index)
|
|
3707
|
-
elif name ==
|
|
4004
|
+
elif name == "r":
|
|
3708
4005
|
self._sim.u(
|
|
3709
4006
|
operation.qubits[0]._index,
|
|
3710
4007
|
float(operation.params[0]),
|
|
3711
4008
|
float(operation.params[1]) - math.pi / 2,
|
|
3712
4009
|
(-1 * float(operation.params[1])) + math.pi / 2,
|
|
3713
4010
|
)
|
|
3714
|
-
elif name ==
|
|
3715
|
-
self._sim.r(
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
elif name ==
|
|
3719
|
-
self._sim.r(
|
|
3720
|
-
|
|
4011
|
+
elif name == "rx":
|
|
4012
|
+
self._sim.r(
|
|
4013
|
+
Pauli.PauliX, float(operation.params[0]), operation.qubits[0]._index
|
|
4014
|
+
)
|
|
4015
|
+
elif name == "ry":
|
|
4016
|
+
self._sim.r(
|
|
4017
|
+
Pauli.PauliY, float(operation.params[0]), operation.qubits[0]._index
|
|
4018
|
+
)
|
|
4019
|
+
elif name == "rz":
|
|
4020
|
+
self._sim.r(
|
|
4021
|
+
Pauli.PauliZ, float(operation.params[0]), operation.qubits[0]._index
|
|
4022
|
+
)
|
|
4023
|
+
elif name == "h":
|
|
3721
4024
|
self._sim.h(operation.qubits[0]._index)
|
|
3722
|
-
elif name ==
|
|
4025
|
+
elif name == "x":
|
|
3723
4026
|
self._sim.x(operation.qubits[0]._index)
|
|
3724
|
-
elif name ==
|
|
4027
|
+
elif name == "y":
|
|
3725
4028
|
self._sim.y(operation.qubits[0]._index)
|
|
3726
|
-
elif name ==
|
|
4029
|
+
elif name == "z":
|
|
3727
4030
|
self._sim.z(operation.qubits[0]._index)
|
|
3728
|
-
elif name ==
|
|
4031
|
+
elif name == "s":
|
|
3729
4032
|
self._sim.s(operation.qubits[0]._index)
|
|
3730
|
-
elif name ==
|
|
4033
|
+
elif name == "sdg":
|
|
3731
4034
|
self._sim.adjs(operation.qubits[0]._index)
|
|
3732
|
-
elif name ==
|
|
4035
|
+
elif name == "sx":
|
|
3733
4036
|
self._sim.mtrx(
|
|
3734
4037
|
[(1 + 1j) / 2, (1 - 1j) / 2, (1 - 1j) / 2, (1 + 1j) / 2],
|
|
3735
4038
|
operation.qubits[0]._index,
|
|
3736
4039
|
)
|
|
3737
|
-
elif name ==
|
|
4040
|
+
elif name == "sxdg":
|
|
3738
4041
|
self._sim.mtrx(
|
|
3739
4042
|
[(1 - 1j) / 2, (1 + 1j) / 2, (1 + 1j) / 2, (1 - 1j) / 2],
|
|
3740
4043
|
operation.qubits[0]._index,
|
|
3741
4044
|
)
|
|
3742
|
-
elif name ==
|
|
4045
|
+
elif name == "t":
|
|
3743
4046
|
self._sim.t(operation.qubits[0]._index)
|
|
3744
|
-
elif name ==
|
|
4047
|
+
elif name == "tdg":
|
|
3745
4048
|
self._sim.adjt(operation.qubits[0]._index)
|
|
3746
|
-
elif name ==
|
|
4049
|
+
elif name == "cu1":
|
|
3747
4050
|
self._sim.mcu(
|
|
3748
|
-
[q._index for q in operation.qubits[0:1]],
|
|
4051
|
+
[q._index for q in operation.qubits[0:1]],
|
|
4052
|
+
operation.qubits[1]._index,
|
|
4053
|
+
0,
|
|
4054
|
+
0,
|
|
4055
|
+
float(operation.params[0]),
|
|
3749
4056
|
)
|
|
3750
|
-
elif name ==
|
|
4057
|
+
elif name == "cu2":
|
|
3751
4058
|
self._sim.mcu(
|
|
3752
4059
|
[q._index for q in operation.qubits[0:1]],
|
|
3753
4060
|
operation.qubits[1]._index,
|
|
@@ -3755,7 +4062,7 @@ class QrackSimulator:
|
|
|
3755
4062
|
float(operation.params[0]),
|
|
3756
4063
|
float(operation.params[1]),
|
|
3757
4064
|
)
|
|
3758
|
-
elif (name ==
|
|
4065
|
+
elif (name == "cu3") or (name == "cu"):
|
|
3759
4066
|
self._sim.mcu(
|
|
3760
4067
|
[q._index for q in operation.qubits[0:1]],
|
|
3761
4068
|
operation.qubits[1]._index,
|
|
@@ -3763,77 +4070,104 @@ class QrackSimulator:
|
|
|
3763
4070
|
float(operation.params[1]),
|
|
3764
4071
|
float(operation.params[2]),
|
|
3765
4072
|
)
|
|
3766
|
-
elif name ==
|
|
3767
|
-
self._sim.mcx(
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
elif name ==
|
|
3771
|
-
self._sim.
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
elif name ==
|
|
4073
|
+
elif name == "cx":
|
|
4074
|
+
self._sim.mcx(
|
|
4075
|
+
[q._index for q in operation.qubits[0:1]], operation.qubits[1]._index
|
|
4076
|
+
)
|
|
4077
|
+
elif name == "cy":
|
|
4078
|
+
self._sim.mcy(
|
|
4079
|
+
[q._index for q in operation.qubits[0:1]], operation.qubits[1]._index
|
|
4080
|
+
)
|
|
4081
|
+
elif name == "cz":
|
|
4082
|
+
self._sim.mcz(
|
|
4083
|
+
[q._index for q in operation.qubits[0:1]], operation.qubits[1]._index
|
|
4084
|
+
)
|
|
4085
|
+
elif name == "ch":
|
|
4086
|
+
self._sim.mch(
|
|
4087
|
+
[q._index for q in operation.qubits[0:1]], operation.qubits[1]._index
|
|
4088
|
+
)
|
|
4089
|
+
elif name == "cp":
|
|
3775
4090
|
self._sim.mcmtrx(
|
|
3776
4091
|
[q._index for q in operation.qubits[0:1]],
|
|
3777
4092
|
[
|
|
3778
4093
|
1,
|
|
3779
4094
|
0,
|
|
3780
4095
|
0,
|
|
3781
|
-
math.cos(float(operation.params[0]))
|
|
4096
|
+
math.cos(float(operation.params[0]))
|
|
4097
|
+
+ 1j * math.sin(float(operation.params[0])),
|
|
3782
4098
|
],
|
|
3783
4099
|
operation.qubits[1]._index,
|
|
3784
4100
|
)
|
|
3785
|
-
elif name ==
|
|
4101
|
+
elif name == "csx":
|
|
3786
4102
|
self._sim.mcmtrx(
|
|
3787
4103
|
[q._index for q in operation.qubits[0:1]],
|
|
3788
4104
|
[(1 + 1j) / 2, (1 - 1j) / 2, (1 - 1j) / 2, (1 + 1j) / 2],
|
|
3789
4105
|
operation.qubits[1]._index,
|
|
3790
4106
|
)
|
|
3791
|
-
elif name ==
|
|
4107
|
+
elif name == "csxdg":
|
|
3792
4108
|
self._sim.mcmtrx(
|
|
3793
4109
|
[q._index for q in operation.qubits[0:1]],
|
|
3794
4110
|
[(1 - 1j) / 2, (1 + 1j) / 2, (1 + 1j) / 2, (1 - 1j) / 2],
|
|
3795
4111
|
operation.qubits[1]._index,
|
|
3796
4112
|
)
|
|
3797
|
-
elif name ==
|
|
3798
|
-
self._sim.mcx(
|
|
4113
|
+
elif name == "dcx":
|
|
4114
|
+
self._sim.mcx(
|
|
4115
|
+
[q._index for q in operation.qubits[0:1]], operation.qubits[1]._index
|
|
4116
|
+
)
|
|
3799
4117
|
self._sim.mcx(operation.qubits[1:2]._index, operation.qubits[0]._index)
|
|
3800
|
-
elif name ==
|
|
3801
|
-
self._sim.mcx(
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
elif name ==
|
|
3805
|
-
self._sim.
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
elif name ==
|
|
3809
|
-
self._sim.
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
elif name ==
|
|
4118
|
+
elif name == "ccx":
|
|
4119
|
+
self._sim.mcx(
|
|
4120
|
+
[q._index for q in operation.qubits[0:2]], operation.qubits[2]._index
|
|
4121
|
+
)
|
|
4122
|
+
elif name == "ccy":
|
|
4123
|
+
self._sim.mcy(
|
|
4124
|
+
[q._index for q in operation.qubits[0:2]], operation.qubits[2]._index
|
|
4125
|
+
)
|
|
4126
|
+
elif name == "ccz":
|
|
4127
|
+
self._sim.mcz(
|
|
4128
|
+
[q._index for q in operation.qubits[0:2]], operation.qubits[2]._index
|
|
4129
|
+
)
|
|
4130
|
+
elif name == "mcx":
|
|
4131
|
+
self._sim.mcx(
|
|
4132
|
+
[q._index for q in operation.qubits[0:-1]], operation.qubits[-1]._index
|
|
4133
|
+
)
|
|
4134
|
+
elif name == "mcy":
|
|
4135
|
+
self._sim.mcy(
|
|
4136
|
+
[q._index for q in operation.qubits[0:-1]], operation.qubits[-1]._index
|
|
4137
|
+
)
|
|
4138
|
+
elif name == "mcz":
|
|
4139
|
+
self._sim.mcz(
|
|
4140
|
+
[q._index for q in operation.qubits[0:-1]], operation.qubits[-1]._index
|
|
4141
|
+
)
|
|
4142
|
+
elif name == "swap":
|
|
3813
4143
|
self._sim.swap(operation.qubits[0]._index, operation.qubits[1]._index)
|
|
3814
|
-
elif name ==
|
|
4144
|
+
elif name == "iswap":
|
|
3815
4145
|
self._sim.iswap(operation.qubits[0]._index, operation.qubits[1]._index)
|
|
3816
|
-
elif name ==
|
|
4146
|
+
elif name == "iswap_dg":
|
|
3817
4147
|
self._sim.adjiswap(operation.qubits[0]._index, operation.qubits[1]._index)
|
|
3818
|
-
elif name ==
|
|
4148
|
+
elif name == "cswap":
|
|
3819
4149
|
self._sim.cswap(
|
|
3820
|
-
[q._index for q in operation.qubits[0:1]],
|
|
4150
|
+
[q._index for q in operation.qubits[0:1]],
|
|
4151
|
+
operation.qubits[1]._index,
|
|
4152
|
+
operation.qubits[2]._index,
|
|
3821
4153
|
)
|
|
3822
|
-
elif name ==
|
|
4154
|
+
elif name == "mcswap":
|
|
3823
4155
|
self._sim.cswap(
|
|
3824
|
-
[q._index for q in operation.qubits[:-2]],
|
|
4156
|
+
[q._index for q in operation.qubits[:-2]],
|
|
4157
|
+
operation.qubits[-2]._index,
|
|
4158
|
+
operation.qubits[-1]._index,
|
|
3825
4159
|
)
|
|
3826
|
-
elif name ==
|
|
4160
|
+
elif name == "reset":
|
|
3827
4161
|
qubits = operation.qubits
|
|
3828
4162
|
for qubit in qubits:
|
|
3829
4163
|
if self._sim.m(qubit._index):
|
|
3830
4164
|
self._sim.x(qubit._index)
|
|
3831
|
-
elif name ==
|
|
4165
|
+
elif name == "measure":
|
|
3832
4166
|
qubits = operation.qubits
|
|
3833
4167
|
clbits = operation.clbits
|
|
3834
4168
|
cregbits = (
|
|
3835
4169
|
operation.register
|
|
3836
|
-
if hasattr(operation,
|
|
4170
|
+
if hasattr(operation, "register")
|
|
3837
4171
|
else len(operation.qubits) * [-1]
|
|
3838
4172
|
)
|
|
3839
4173
|
|
|
@@ -3860,30 +4194,30 @@ class QrackSimulator:
|
|
|
3860
4194
|
self._classical_register & (~regbit)
|
|
3861
4195
|
) | (qubit_outcome << cregbit)
|
|
3862
4196
|
|
|
3863
|
-
elif name ==
|
|
4197
|
+
elif name == "bfunc":
|
|
3864
4198
|
mask = int(operation.mask, 16)
|
|
3865
4199
|
relation = operation.relation
|
|
3866
4200
|
val = int(operation.val, 16)
|
|
3867
4201
|
|
|
3868
4202
|
cregbit = operation.register
|
|
3869
|
-
cmembit = operation.memory if hasattr(operation,
|
|
4203
|
+
cmembit = operation.memory if hasattr(operation, "memory") else None
|
|
3870
4204
|
|
|
3871
4205
|
compared = (self._classical_register & mask) - val
|
|
3872
4206
|
|
|
3873
|
-
if relation ==
|
|
4207
|
+
if relation == "==":
|
|
3874
4208
|
outcome = compared == 0
|
|
3875
|
-
elif relation ==
|
|
4209
|
+
elif relation == "!=":
|
|
3876
4210
|
outcome = compared != 0
|
|
3877
|
-
elif relation ==
|
|
4211
|
+
elif relation == "<":
|
|
3878
4212
|
outcome = compared < 0
|
|
3879
|
-
elif relation ==
|
|
4213
|
+
elif relation == "<=":
|
|
3880
4214
|
outcome = compared <= 0
|
|
3881
|
-
elif relation ==
|
|
4215
|
+
elif relation == ">":
|
|
3882
4216
|
outcome = compared > 0
|
|
3883
|
-
elif relation ==
|
|
4217
|
+
elif relation == ">=":
|
|
3884
4218
|
outcome = compared >= 0
|
|
3885
4219
|
else:
|
|
3886
|
-
raise QrackError(
|
|
4220
|
+
raise QrackError("Invalid boolean function relation.")
|
|
3887
4221
|
|
|
3888
4222
|
# Store outcome in register and optionally memory slot
|
|
3889
4223
|
regbit = 1 << cregbit
|
|
@@ -3926,7 +4260,9 @@ class QrackSimulator:
|
|
|
3926
4260
|
result |= qubit_outcome << index
|
|
3927
4261
|
measure_results = [result]
|
|
3928
4262
|
else:
|
|
3929
|
-
measure_results = self._sim.measure_shots(
|
|
4263
|
+
measure_results = self._sim.measure_shots(
|
|
4264
|
+
[q._index for q in measure_qubit], num_samples
|
|
4265
|
+
)
|
|
3930
4266
|
|
|
3931
4267
|
data = []
|
|
3932
4268
|
for sample in measure_results:
|
|
@@ -3968,21 +4304,21 @@ class QrackSimulator:
|
|
|
3968
4304
|
for opcount in range(len(instructions)):
|
|
3969
4305
|
operation = instructions[opcount]
|
|
3970
4306
|
|
|
3971
|
-
if operation.name ==
|
|
4307
|
+
if operation.name == "id" or operation.name == "barrier":
|
|
3972
4308
|
continue
|
|
3973
4309
|
|
|
3974
4310
|
if is_initializing and (
|
|
3975
|
-
(operation.name ==
|
|
4311
|
+
(operation.name == "measure") or (operation.name == "reset")
|
|
3976
4312
|
):
|
|
3977
4313
|
continue
|
|
3978
4314
|
|
|
3979
4315
|
is_initializing = False
|
|
3980
4316
|
|
|
3981
|
-
if (operation.name ==
|
|
4317
|
+
if (operation.name == "measure") or (operation.name == "reset"):
|
|
3982
4318
|
if boundary_start == -1:
|
|
3983
4319
|
boundary_start = opcount
|
|
3984
4320
|
|
|
3985
|
-
if (boundary_start != -1) and (operation.name !=
|
|
4321
|
+
if (boundary_start != -1) and (operation.name != "measure"):
|
|
3986
4322
|
shotsPerLoop = 1
|
|
3987
4323
|
shotLoopMax = self._shots
|
|
3988
4324
|
self._sample_measure = False
|