pyqrack-cpu 1.34.0__py3-none-win_amd64.whl → 1.34.5__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/qrack_circuit.py CHANGED
@@ -12,9 +12,10 @@ _IS_QISKIT_AVAILABLE = True
12
12
  try:
13
13
  from qiskit.circuit.quantumcircuit import QuantumCircuit
14
14
  from qiskit.compiler.transpiler import transpile
15
- from qiskit.circuit.library import U3Gate, UCGate
15
+ from qiskit.circuit.library import UCGate
16
16
  import numpy as np
17
17
  import math
18
+ import sys
18
19
  except ImportError:
19
20
  _IS_QISKIT_AVAILABLE = False
20
21
 
@@ -32,22 +33,6 @@ except ImportError:
32
33
  _IS_TENSORCIRCUIT_AVAILABLE = False
33
34
 
34
35
 
35
- def euler_angles_1q(m):
36
- phase = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) ** (-1.0/2.0)
37
- U = [[phase * m[0][0], phase * m[0][1]], [phase * m[1][0], phase * m[1][1]]]
38
-
39
- theta = 2 * math.atan2(abs(U[1][0]), abs(U[0][0]))
40
-
41
- # Find phi and lambda
42
- phiplambda = 2 * np.angle(U[1][1])
43
- phimlambda = 2 * np.angle(U[1][0])
44
-
45
- phi = (phiplambda + phimlambda) / 2.0
46
- lamb = (phiplambda - phimlambda) / 2.0
47
-
48
- return theta, phi, lamb
49
-
50
-
51
36
  class QrackCircuit:
52
37
  """Class that exposes the QCircuit class of Qrack
53
38
 
@@ -85,6 +70,50 @@ class QrackCircuit:
85
70
  t = [(c.real, c.imag) for c in a]
86
71
  return self._double_byref([float(item) for sublist in t for item in sublist])
87
72
 
73
+ def _mtrx_to_u4(m):
74
+ nrm = abs(m[0])
75
+ if (nrm * nrm) < sys.float_info.epsilon:
76
+ phase = 1.0 + 0.0j
77
+ th = math.pi / 2;
78
+ else:
79
+ phase = m[0] / nrm
80
+ if nrm > 1.0:
81
+ nrm = 1.0
82
+ th = math.acos(nrm)
83
+
84
+ nrm1 = abs(m[1])
85
+ nrm2 = abs(m[2])
86
+ nrm1 *= nrm1
87
+ nrm2 *= nrm2
88
+ if (nrm1 < sys.float_info.epsilon) or (nrm2 < sys.float_info.epsilon):
89
+ ph = np.angle(m[3] / phase)
90
+ lm = 0.0
91
+ else:
92
+ ph = np.angle(m[2] / phase)
93
+ lm = np.angle(-m[1] / phase)
94
+
95
+ return th, ph, lm, np.angle(phase)
96
+
97
+ def _u3_to_mtrx(params):
98
+ th = float(params[0])
99
+ ph = float(params[1])
100
+ lm = float(params[2])
101
+
102
+ c = math.cos(th / 2)
103
+ s = math.sin(th / 2)
104
+ el = np.exp(1j * lm)
105
+ ep = np.exp(1j * ph)
106
+
107
+ return [c + 0j, -el * s, ep * s, ep * el * c]
108
+
109
+ def _u4_to_mtrx(params):
110
+ m = _u3_to_mtrx(params)
111
+ g = np.exp(1j * float(params[3]))
112
+ for i in range(4):
113
+ m[i] *= g
114
+
115
+ return m
116
+
88
117
  def clone(self):
89
118
  """Make a new circuit that is an exact clone of this circuit
90
119
 
@@ -302,86 +331,52 @@ class QrackCircuit:
302
331
 
303
332
  i = 0
304
333
  num_qubits = int(tokens[i])
305
- i = i + 1
334
+ i += 1
306
335
  circ = QuantumCircuit(num_qubits)
307
336
 
308
337
  num_gates = int(tokens[i])
309
- i = i + 1
338
+ i += 1
310
339
 
311
340
  for g in range(num_gates):
312
341
  target = int(tokens[i])
313
- i = i + 1
342
+ i += 1
314
343
 
315
344
  control_count = int(tokens[i])
316
- i = i + 1
345
+ i += 1
317
346
  controls = []
318
347
  for j in range(control_count):
319
348
  controls.append(int(tokens[i]))
320
- i = i + 1
349
+ i += 1
321
350
 
322
351
  payload_count = int(tokens[i])
323
- i = i + 1
352
+ i += 1
324
353
  payloads = {}
325
354
  for j in range(payload_count):
326
355
  key = int(tokens[i])
327
- i = i + 1
328
- op = np.zeros((2,2), dtype=complex)
329
- row = []
330
- for _ in range(2):
331
- amp = tokens[i].replace("(","").replace(")","").split(',')
332
- row.append(float(amp[0]) + float(amp[1])*1j)
333
- i = i + 1
334
- l = math.sqrt(np.real(row[0] * np.conj(row[0]) + row[1] * np.conj(row[1])))
335
- op[0][0] = row[0] / l
336
- op[0][1] = row[1] / l
337
-
338
- if np.abs(op[0][0] - row[0]) > 1e-5:
339
- print("Warning: gate ", str(g), ", payload ", str(j), " might not be unitary!")
340
- if np.abs(op[0][1] - row[1]) > 1e-5:
341
- print("Warning: gate ", str(g), ", payload ", str(j), " might not be unitary!")
342
-
343
- row = []
344
- for _ in range(2):
356
+ i += 1
357
+
358
+ mtrx = []
359
+ for _ in range(4):
345
360
  amp = tokens[i].replace("(","").replace(")","").split(',')
346
- row.append(float(amp[0]) + float(amp[1])*1j)
347
- i = i + 1
348
- l = math.sqrt(np.real(row[0] * np.conj(row[0]) + row[1] * np.conj(row[1])))
349
- op[1][0] = row[0] / l
350
- op[1][1] = row[1] / l
351
-
352
- ph = np.real(np.log(np.linalg.det(op)) / 1j)
353
-
354
- op[1][0] = -np.exp(1j * ph) * np.conj(op[0][1])
355
- op[1][1] = np.exp(1j * ph) * np.conj(op[0][0])
356
-
357
- if np.abs(op[1][0] - row[0]) > 1e-5:
358
- print("Warning: gate ", str(g), ", payload ", str(j), " might not be unitary!")
359
- if np.abs(op[1][1] - row[1]) > 1e-5:
360
- print("Warning: gate ", str(g), ", payload ", str(j), " might not be unitary!")
361
-
362
- # Qiskit has a lower tolerance for deviation from numerically unitary.
363
- payloads[key] = np.array(op)
364
-
365
- gate_list = []
366
- control_pow = 1 << control_count
367
- pLen = len(payloads)
368
- if (pLen == 1) or ((control_pow - pLen) > (1 << 15)):
369
- for c, p in payloads.items():
370
- theta, phi, lam = euler_angles_1q(p)
371
- if control_count > 0:
372
- circ.append(
373
- U3Gate(theta, phi, lam).control(num_ctrl_qubits=control_count, ctrl_state=c),
374
- controls + [target]
375
- )
376
- else:
377
- circ.append(U3Gate(theta, phi, lam), [target])
378
- else:
379
- for j in range(control_pow):
380
- if j in payloads:
381
- gate_list.append(payloads[j])
382
- else:
383
- gate_list.append(np.array([[1, 0],[0, 1]]))
384
- circ.append(UCGate(gate_list), controls + [target])
361
+ mtrx.append(float(amp[0]) + float(amp[1])*1j)
362
+ i += 1
363
+
364
+ op = np.eye(2, dtype=complex)
365
+ op[0][0] = mtrx[0]
366
+ op[0][1] = mtrx[1]
367
+ op[1][0] = mtrx[2]
368
+ op[1][1] = mtrx[3]
369
+
370
+ payloads[key] = op
371
+
372
+ identity = np.eye(2, dtype=complex)
373
+ gate_list=[]
374
+ for j in range(1 << control_count):
375
+ if j in payloads:
376
+ gate_list.append(payloads[j])
377
+ else:
378
+ gate_list.append(identity)
379
+ circ.append(UCGate(gate_list), controls + [target])
385
380
 
386
381
  return circ
387
382
 
@@ -403,31 +398,25 @@ class QrackCircuit:
403
398
  )
404
399
 
405
400
  out = QrackCircuit()
406
-
407
- basis_gates = ["u", "cx"]
408
- circ = transpile(circ, basis_gates=basis_gates, optimization_level=3)
401
+ basis_gates = ["x", "y", "z", "u", "cx", "cy", "cz", "cu"]
402
+ circ = transpile(circ, basis_gates=basis_gates, optimization_level=0)
409
403
  for gate in circ.data:
410
404
  o = gate.operation
411
- if o.name == "u":
412
- th = float(o.params[0])
413
- ph = float(o.params[1])
414
- lm = float(o.params[2])
415
405
 
416
- c = math.cos(th / 2)
417
- s = math.sin(th / 2)
406
+ op = []
407
+ if o.name in ["x", "cx"]:
408
+ op = [0, 1, 1, 0]
409
+ elif o.name in ["y", "cy"]:
410
+ op = [0, -1j, 1j, 0]
411
+ elif o.name in ["z", "cz"]:
412
+ op = [1, 0, 0, -1]
413
+ else:
414
+ op = QrackCircuit._u3_to_mtrx(o.params)
418
415
 
419
- op = [
420
- c + 0j,
421
- -np.exp(1j * lm) * s,
422
- np.exp(1j * ph) * s,
423
- np.exp(1j * (ph + lm)) * c
424
- ]
416
+ if o.name in ["x", "y", "z", "u"]:
425
417
  out.mtrx(op, circ.find_bit(gate.qubits[0])[0])
426
418
  else:
427
- ctrls = []
428
- for c in gate.qubits[0:1]:
429
- ctrls.append(circ.find_bit(c)[0])
430
- out.ucmtrx(ctrls, [0, 1, 1, 0], circ.find_bit(gate.qubits[1])[0], 1)
419
+ out.ucmtrx([circ.find_bit(gate.qubits[0])[0]], op, circ.find_bit(gate.qubits[1])[0], 1)
431
420
 
432
421
  return out
433
422
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyqrack-cpu
3
- Version: 1.34.0
3
+ Version: 1.34.5
4
4
  Summary: pyqrack - Pure Python vm6502q/qrack Wrapper
5
5
  Home-page: https://github.com/vm6502q/pyqrack
6
6
  Author: Daniel Strano
@@ -1,17 +1,17 @@
1
1
  pyqrack/__init__.py,sha256=gDz6LYCK_3GgGF973p3OGPfocfPgEs-qWaiL_tCw1fs,594
2
2
  pyqrack/neuron_activation_fn.py,sha256=cvljN3vvoH71uPva8EFKxJomgiQMo7zqud2JoSpKTiM,615
3
3
  pyqrack/pauli.py,sha256=NgtZd4aBN4l8Car14Ris9lZ1Y5JDfNNCN7kDRuo9vWk,673
4
- pyqrack/qrack_circuit.py,sha256=5UDALrvX4c-8afIB6ANGnfwiszHEwNLR_A-QUrVzk7Y,20900
4
+ pyqrack/qrack_circuit.py,sha256=nzEa_E6Q9H1aMjFoM8B0osQTvhDTb1g-Fpzp0vWvRUw,19472
5
5
  pyqrack/qrack_neuron.py,sha256=kMQH2vlajXvkrycNcCs1A1odyp8-CMmaJKEujP4mi0I,9086
6
6
  pyqrack/qrack_simulator.py,sha256=UN2q0g5pmKukliPKQyfBHk3HDMRa5QmVv6srIMLjuxU,137205
7
7
  pyqrack/quimb_circuit_type.py,sha256=fNsmfK9JoNdYN1_Clm9pmS_FTinNsGKJnKQID6L4Bgk,638
8
8
  pyqrack/qrack_system/__init__.py,sha256=PUterej-xpA4BqFmiBrQCMeTQlsRf-K8Dxnwp-iVvUQ,343
9
9
  pyqrack/qrack_system/qrack_system.py,sha256=fj58altw0xryjrb-Oi-S_HDcUb2Ft0Alp1UNOvtSF9E,43081
10
- pyqrack/qrack_system/qrack_lib/qrack_pinvoke.dll,sha256=B5Rj3jKtrJqxGcH3kjiZQj1B848ekp_Bgs-nZrxujOo,1694720
10
+ pyqrack/qrack_system/qrack_lib/qrack_pinvoke.dll,sha256=tPhuwqeagQ3dtkB_j3jodKcox_5LRGVb30SHAPrRE68,1696768
11
11
  pyqrack/util/__init__.py,sha256=cx9yH6Px9cIpBdLO3rftxscbXKUneB36nGRoA68x42c,341
12
12
  pyqrack/util/convert_qiskit_circuit_to_qasm_experiment.py,sha256=tcICZbIhTpM4hU_OfiS_n142cVoER9vR3ZWMaVf9-Zs,2126
13
- pyqrack_cpu-1.34.0.dist-info/LICENSE,sha256=IdAVedmFOPQtHi_XeEI9OhJwUuwlT6tCJwrT55zAn3w,1090
14
- pyqrack_cpu-1.34.0.dist-info/METADATA,sha256=3nM6Q9NQNbVlbZkIM6VaTWLQ3E0R0g-fi-ZX32weCzw,5948
15
- pyqrack_cpu-1.34.0.dist-info/WHEEL,sha256=JMWfR_Dj7ISokcwe0cBhCfK6JKnIi-ZX11L6d_ntt6o,98
16
- pyqrack_cpu-1.34.0.dist-info/top_level.txt,sha256=YE_3q9JTGRLMilNg2tGP1y7uU-Dx8PDao2OhwoIbv8E,8
17
- pyqrack_cpu-1.34.0.dist-info/RECORD,,
13
+ pyqrack_cpu-1.34.5.dist-info/LICENSE,sha256=IdAVedmFOPQtHi_XeEI9OhJwUuwlT6tCJwrT55zAn3w,1090
14
+ pyqrack_cpu-1.34.5.dist-info/METADATA,sha256=SE4H2whiLPlHDGuJS1esH_tkDYnhJJlOmHgKJskl_5I,5948
15
+ pyqrack_cpu-1.34.5.dist-info/WHEEL,sha256=JMWfR_Dj7ISokcwe0cBhCfK6JKnIi-ZX11L6d_ntt6o,98
16
+ pyqrack_cpu-1.34.5.dist-info/top_level.txt,sha256=YE_3q9JTGRLMilNg2tGP1y7uU-Dx8PDao2OhwoIbv8E,8
17
+ pyqrack_cpu-1.34.5.dist-info/RECORD,,