pyqrack-cuda 1.34.0__tar.gz → 1.34.5__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 (26) hide show
  1. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5}/Makefile +1 -1
  2. {pyqrack_cuda-1.34.0/pyqrack_cuda.egg-info → pyqrack_cuda-1.34.5}/PKG-INFO +1 -1
  3. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5}/pyqrack/qrack_circuit.py +88 -99
  4. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5/pyqrack_cuda.egg-info}/PKG-INFO +1 -1
  5. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5}/pyqrack_cuda.egg-info/SOURCES.txt +0 -1
  6. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5}/setup.py +1 -1
  7. pyqrack_cuda-1.34.0/pyqrack/qrack_system/qrack_lib/libqrack_pinvoke.so +0 -0
  8. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5}/LICENSE +0 -0
  9. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5}/MANIFEST.in +0 -0
  10. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5}/README.md +0 -0
  11. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5}/pyproject.toml +0 -0
  12. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5}/pyqrack/__init__.py +0 -0
  13. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5}/pyqrack/neuron_activation_fn.py +0 -0
  14. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5}/pyqrack/pauli.py +0 -0
  15. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5}/pyqrack/qrack_neuron.py +0 -0
  16. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5}/pyqrack/qrack_simulator.py +0 -0
  17. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5}/pyqrack/qrack_system/__init__.py +0 -0
  18. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5}/pyqrack/qrack_system/qrack_system.py +0 -0
  19. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5}/pyqrack/quimb_circuit_type.py +0 -0
  20. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5}/pyqrack/util/__init__.py +0 -0
  21. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5}/pyqrack/util/convert_qiskit_circuit_to_qasm_experiment.py +0 -0
  22. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5}/pyqrack_cuda.egg-info/dependency_links.txt +0 -0
  23. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5}/pyqrack_cuda.egg-info/not-zip-safe +0 -0
  24. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5}/pyqrack_cuda.egg-info/requires.txt +0 -0
  25. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5}/pyqrack_cuda.egg-info/top_level.txt +0 -0
  26. {pyqrack_cuda-1.34.0 → pyqrack_cuda-1.34.5}/setup.cfg +0 -0
@@ -18,7 +18,7 @@ help:
18
18
  build-deps:
19
19
  ifneq ($(OS),Windows_NT)
20
20
  ifeq ($(QRACK_PRESENT),)
21
- git clone https://github.com/unitaryfund/qrack.git; cd qrack; git checkout d102dd0b166452c47027698eb25ef1430ff50bed; cd ..
21
+ git clone https://github.com/unitaryfund/qrack.git; cd qrack; git checkout 0e8b70f19c0f08a700d9ee63bf1a4b204a746235; cd ..
22
22
  endif
23
23
  mkdir -p qrack/build
24
24
  ifeq ($(UNAME_S),Linux)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyqrack-cuda
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
@@ -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-cuda
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
@@ -13,7 +13,6 @@ pyqrack/qrack_simulator.py
13
13
  pyqrack/quimb_circuit_type.py
14
14
  pyqrack/qrack_system/__init__.py
15
15
  pyqrack/qrack_system/qrack_system.py
16
- pyqrack/qrack_system/qrack_lib/libqrack_pinvoke.so
17
16
  pyqrack/util/__init__.py
18
17
  pyqrack/util/convert_qiskit_circuit_to_qasm_experiment.py
19
18
  pyqrack_cuda.egg-info/PKG-INFO
@@ -7,7 +7,7 @@ from setuptools import setup
7
7
  from setuptools.command.build_py import build_py
8
8
 
9
9
 
10
- VERSION = "1.34.0"
10
+ VERSION = "1.34.5"
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