qoro-divi 0.3.4__py3-none-any.whl → 0.4.0__py3-none-any.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 qoro-divi might be problematic. Click here for more details.
- divi/backends/__init__.py +1 -1
- divi/backends/_circuit_runner.py +42 -0
- divi/backends/_parallel_simulator.py +145 -49
- divi/backends/_qoro_service.py +451 -182
- divi/backends/_qpu_system.py +77 -3
- divi/circuits/_core.py +124 -4
- divi/circuits/qasm.py +20 -3
- divi/extern/cirq/_validator.py +12 -3
- divi/qprog/__init__.py +1 -0
- divi/qprog/algorithms/_ansatze.py +112 -12
- divi/qprog/algorithms/_qaoa.py +179 -110
- divi/qprog/algorithms/_vqe.py +192 -58
- divi/qprog/batch.py +270 -51
- divi/qprog/exceptions.py +9 -0
- divi/qprog/optimizers.py +336 -51
- divi/qprog/quantum_program.py +162 -339
- divi/qprog/variational_quantum_algorithm.py +786 -0
- divi/qprog/workflows/_graph_partitioning.py +43 -38
- divi/qprog/workflows/_qubo_partitioning.py +41 -24
- divi/qprog/workflows/_vqe_sweep.py +67 -39
- divi/reporting/_pbar.py +51 -9
- divi/reporting/_qlogger.py +35 -1
- divi/reporting/_reporter.py +11 -20
- divi/utils.py +100 -4
- {qoro_divi-0.3.4.dist-info → qoro_divi-0.4.0.dist-info}/METADATA +16 -1
- {qoro_divi-0.3.4.dist-info → qoro_divi-0.4.0.dist-info}/RECORD +30 -28
- {qoro_divi-0.3.4.dist-info → qoro_divi-0.4.0.dist-info}/LICENSE +0 -0
- {qoro_divi-0.3.4.dist-info → qoro_divi-0.4.0.dist-info}/LICENSES/.license-header +0 -0
- {qoro_divi-0.3.4.dist-info → qoro_divi-0.4.0.dist-info}/LICENSES/Apache-2.0.txt +0 -0
- {qoro_divi-0.3.4.dist-info → qoro_divi-0.4.0.dist-info}/WHEEL +0 -0
divi/utils.py
CHANGED
|
@@ -10,11 +10,88 @@ import pennylane as qml
|
|
|
10
10
|
import scipy.sparse as sps
|
|
11
11
|
|
|
12
12
|
|
|
13
|
+
def hamiltonian_to_pauli_string(hamiltonian: qml.Hamiltonian, n_qubits: int) -> str:
|
|
14
|
+
"""
|
|
15
|
+
Convert a QNode Hamiltonian to a semicolon-separated string of Pauli operators.
|
|
16
|
+
|
|
17
|
+
Each term in the Hamiltonian is represented as a string of Pauli letters ('I', 'X', 'Y', 'Z'),
|
|
18
|
+
one per qubit. Multiple terms are separated by semicolons.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
hamiltonian (qml.Hamiltonian): The Pennylane Hamiltonian object to convert.
|
|
22
|
+
n_qubits (int): Number of qubits to represent in the string.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
str: The Hamiltonian as a semicolon-separated string of Pauli operators.
|
|
26
|
+
|
|
27
|
+
Raises:
|
|
28
|
+
ValueError: If an unknown Pauli operator is encountered or wire index is out of range.
|
|
29
|
+
"""
|
|
30
|
+
pauli_letters = {"PauliX": "X", "PauliY": "Y", "PauliZ": "Z"}
|
|
31
|
+
identity_row = np.full(n_qubits, "I", dtype="<U1")
|
|
32
|
+
|
|
33
|
+
terms = []
|
|
34
|
+
for term in hamiltonian.operands:
|
|
35
|
+
op = term.base if isinstance(term, qml.ops.SProd) else term
|
|
36
|
+
ops = op.operands if isinstance(op, qml.ops.Prod) else [op]
|
|
37
|
+
|
|
38
|
+
paulis = identity_row.copy()
|
|
39
|
+
for p in ops:
|
|
40
|
+
# Better fallback logic with validation
|
|
41
|
+
if p.name in pauli_letters:
|
|
42
|
+
pauli = pauli_letters[p.name]
|
|
43
|
+
elif p.name.startswith("Pauli") and len(p.name) > 5:
|
|
44
|
+
pauli = p.name[5:] # Only if safe to slice
|
|
45
|
+
else:
|
|
46
|
+
raise ValueError(
|
|
47
|
+
f"Unknown Pauli operator: {p.name}. "
|
|
48
|
+
"Expected 'PauliX', 'PauliY', 'PauliZ', or a name starting with 'Pauli'."
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# Bounds checking for wire indices
|
|
52
|
+
if not p.wires:
|
|
53
|
+
raise ValueError(f"Pauli operator {p.name} has no wires")
|
|
54
|
+
|
|
55
|
+
wire = int(p.wires[0])
|
|
56
|
+
if wire < 0 or wire >= n_qubits:
|
|
57
|
+
raise ValueError(
|
|
58
|
+
f"Wire index {wire} out of range for {n_qubits} qubits. "
|
|
59
|
+
f"Valid range: [0, {n_qubits - 1}]"
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
paulis[wire] = pauli
|
|
63
|
+
terms.append("".join(paulis))
|
|
64
|
+
|
|
65
|
+
return ";".join(terms)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def reverse_dict_endianness(
|
|
69
|
+
probs_dict: dict[str, dict[str, float]],
|
|
70
|
+
) -> dict[str, dict[str, float]]:
|
|
71
|
+
"""Reverse endianness of all bitstrings in a dictionary of probability distributions."""
|
|
72
|
+
return {
|
|
73
|
+
tag: {bitstring[::-1]: prob for bitstring, prob in probs.items()}
|
|
74
|
+
for tag, probs in probs_dict.items()
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
|
|
13
78
|
def _is_sanitized(
|
|
14
79
|
qubo_matrix: np.ndarray | sps.spmatrix,
|
|
15
80
|
) -> np.ndarray | sps.spmatrix:
|
|
16
|
-
|
|
81
|
+
"""
|
|
82
|
+
Check if a QUBO matrix is either symmetric or upper triangular.
|
|
83
|
+
|
|
84
|
+
This function validates that the input QUBO matrix is in a proper format
|
|
85
|
+
for conversion to an Ising Hamiltonian. The matrix should be either
|
|
86
|
+
symmetric (equal to its transpose) or upper triangular.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
qubo_matrix (np.ndarray | sps.spmatrix): The QUBO matrix to validate.
|
|
90
|
+
Can be a dense NumPy array or a sparse SciPy matrix.
|
|
17
91
|
|
|
92
|
+
Returns:
|
|
93
|
+
bool: True if the matrix is symmetric or upper triangular, False otherwise.
|
|
94
|
+
"""
|
|
18
95
|
is_sparse = sps.issparse(qubo_matrix)
|
|
19
96
|
|
|
20
97
|
return (
|
|
@@ -33,18 +110,37 @@ def _is_sanitized(
|
|
|
33
110
|
def convert_qubo_matrix_to_pennylane_ising(
|
|
34
111
|
qubo_matrix: np.ndarray | sps.spmatrix,
|
|
35
112
|
) -> tuple[qml.operation.Operator, float]:
|
|
36
|
-
"""
|
|
113
|
+
"""
|
|
114
|
+
Convert a QUBO matrix to an Ising Hamiltonian in PennyLane format.
|
|
37
115
|
|
|
38
116
|
The conversion follows the mapping from QUBO variables x_i ∈ {0,1} to
|
|
39
117
|
Ising variables σ_i ∈ {-1,1} via the transformation x_i = (1 - σ_i)/2. This
|
|
40
118
|
transforms a QUBO minimization problem into an equivalent Ising minimization
|
|
41
119
|
problem.
|
|
42
120
|
|
|
121
|
+
The function handles both dense NumPy arrays and sparse SciPy matrices efficiently.
|
|
122
|
+
If the input matrix is neither symmetric nor upper triangular, it will be
|
|
123
|
+
symmetrized automatically with a warning.
|
|
124
|
+
|
|
43
125
|
Args:
|
|
44
|
-
qubo_matrix: The QUBO matrix Q where the
|
|
126
|
+
qubo_matrix (np.ndarray | sps.spmatrix): The QUBO matrix Q where the
|
|
127
|
+
objective is to minimize x^T Q x. Can be a dense NumPy array or a
|
|
128
|
+
sparse SciPy matrix (any format). Should be square and either
|
|
129
|
+
symmetric or upper triangular.
|
|
45
130
|
|
|
46
131
|
Returns:
|
|
47
|
-
|
|
132
|
+
tuple[qml.operation.Operator, float]: A tuple containing:
|
|
133
|
+
- Ising Hamiltonian as a PennyLane operator (sum of Pauli Z terms)
|
|
134
|
+
- Constant offset term to be added to energy calculations
|
|
135
|
+
|
|
136
|
+
Raises:
|
|
137
|
+
UserWarning: If the QUBO matrix is neither symmetric nor upper triangular.
|
|
138
|
+
|
|
139
|
+
Example:
|
|
140
|
+
>>> import numpy as np
|
|
141
|
+
>>> qubo = np.array([[1, 2], [0, 3]])
|
|
142
|
+
>>> hamiltonian, offset = convert_qubo_matrix_to_pennylane_ising(qubo)
|
|
143
|
+
>>> print(f"Offset: {offset}")
|
|
48
144
|
"""
|
|
49
145
|
|
|
50
146
|
if not _is_sanitized(qubo_matrix):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: qoro-divi
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: A Python library to automate generating, parallelizing, and executing quantum programs.
|
|
5
5
|
Author: Ahmed Darwish
|
|
6
6
|
Author-email: ahmed@qoroquantum.de
|
|
@@ -17,6 +17,7 @@ Requires-Dist: networkx (>=3.5,<4.0)
|
|
|
17
17
|
Requires-Dist: pennylane (>=0.42.3,<0.43.0)
|
|
18
18
|
Requires-Dist: ply (>=3.11,<4.0)
|
|
19
19
|
Requires-Dist: pymetis (>=2025.1.1,<2026.0.0)
|
|
20
|
+
Requires-Dist: pymoo (>=0.6.1.5,<0.7.0.0)
|
|
20
21
|
Requires-Dist: python-dotenv (>=1.1.1,<2.0.0)
|
|
21
22
|
Requires-Dist: qiskit (<2.0)
|
|
22
23
|
Requires-Dist: qiskit-aer (>=0.17.1,<0.18.0)
|
|
@@ -62,3 +63,17 @@ pip install qoro-divi
|
|
|
62
63
|
- Full documentation is available at: <https://docs.qoroquantum.net/divi>
|
|
63
64
|
- Tutorials can be found in the `tutorials` folder.
|
|
64
65
|
|
|
66
|
+
## 🧪 Testing
|
|
67
|
+
|
|
68
|
+
To run the test suite:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# Run all tests
|
|
72
|
+
pytest
|
|
73
|
+
|
|
74
|
+
# Run only API tests (requires API token)
|
|
75
|
+
pytest --run-api-tests
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Note:** Some tests require a Qoro API token to test the cloud REST API. Set the `QORO_API_KEY` environment variable or use the `--api-token` option. For local development, you can create a `.env`.
|
|
79
|
+
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
divi/__init__.py,sha256=SyBWflbDS6qGEtHg-AfzD1TRNgfXoW2H5qTYGJ-W3XQ,167
|
|
2
|
-
divi/backends/__init__.py,sha256=
|
|
3
|
-
divi/backends/_circuit_runner.py,sha256=
|
|
4
|
-
divi/backends/_parallel_simulator.py,sha256=
|
|
5
|
-
divi/backends/_qoro_service.py,sha256=
|
|
6
|
-
divi/backends/_qpu_system.py,sha256=
|
|
2
|
+
divi/backends/__init__.py,sha256=xi1thgxkqNVIbKO1ZOkn1qewlO8iV8dYijUPIn1WxzU,275
|
|
3
|
+
divi/backends/_circuit_runner.py,sha256=IDObfDWvFMSXi0JODul1x6Fg9MwTEOGGLYdGiE6KCDg,1988
|
|
4
|
+
divi/backends/_parallel_simulator.py,sha256=J2EfRUl8VlmUrxPYbE3HdCMN-xlS5vZnWePldEapMH0,13517
|
|
5
|
+
divi/backends/_qoro_service.py,sha256=R31waE67ZmyTNuVPa2XDyisouIPqLtjjEfD9QVlZmTA,24313
|
|
6
|
+
divi/backends/_qpu_system.py,sha256=Qrn7lp4NsN5rP7AEpo9MCGv7ndDAuQHvbHB1KD-Upgo,2863
|
|
7
7
|
divi/circuits/__init__.py,sha256=Wl4BF0_TwG1Ol4oaftCD5lpkgS9us9EW7F4hu6r_eXM,151
|
|
8
|
-
divi/circuits/_core.py,sha256=
|
|
9
|
-
divi/circuits/qasm.py,sha256=
|
|
8
|
+
divi/circuits/_core.py,sha256=DzD-0F9YmT7Qdj6lzwm6X41nnmZU_TDfr06Y1Od7KZI,9286
|
|
9
|
+
divi/circuits/qasm.py,sha256=6FDcNNdXGfYVGK64YTt22r2Jqz6c_TzNBC0NRjFs34g,8116
|
|
10
10
|
divi/circuits/qem.py,sha256=o6rMPUcxLuCBitBb8-QcxveUiKZVsP3HMamxyVFLi6M,6805
|
|
11
11
|
divi/extern/cirq/__init__.py,sha256=6NjP3TlQn_oNkg8VrKvEIoYQxB5Bx0mLLFOT3SXReTc,371
|
|
12
12
|
divi/extern/cirq/_lexer.py,sha256=x5UArrnN_JEyiq7E02ikq0wdmqZ2vEQ3_FADL1LIhQI,3187
|
|
13
13
|
divi/extern/cirq/_parser.py,sha256=z_bSn4m03-sfRlN8eL99Mo4LnjY-zmR-Xt6UrjzstZc,29279
|
|
14
14
|
divi/extern/cirq/_qasm_export.py,sha256=8C5xLYvIIkQTWWAAYo7ZjwtQjvYXNSflbf5UyUx6YUE,1024
|
|
15
15
|
divi/extern/cirq/_qasm_import.py,sha256=HbehrgfLl3iDdRyWr4o26Bek3ZpN-_dvNVSexl5-aVE,969
|
|
16
|
-
divi/extern/cirq/_validator.py,sha256=
|
|
16
|
+
divi/extern/cirq/_validator.py,sha256=od1vilsqn0T8wYAU1u1Rr5pZfjyaqHlIMwD_NWzUU4Y,20875
|
|
17
17
|
divi/extern/cirq/exception.py,sha256=w1w2vSubOGMRmyKBFqXejxfeIAzkPZ6V7gSrDX_ap4A,765
|
|
18
18
|
divi/extern/scipy/_cobyla.py,sha256=cnCf5AsOM8JWIMiujuUbWMNOgmUr3ZET9y04hUyumHs,10937
|
|
19
19
|
divi/extern/scipy/pyprima/LICENCE.txt,sha256=mXN5ssG_U6OR0v0yldznW_PJTtKNZIgu3jDRtRjLDdY,1533
|
|
@@ -43,26 +43,28 @@ divi/extern/scipy/pyprima/common/present.py,sha256=caedmqSB5ggGXNfky0A6v6FAdyaEG
|
|
|
43
43
|
divi/extern/scipy/pyprima/common/ratio.py,sha256=taadehpW0c3ULUggH5frIMpvTom53dsEhvFaXrIKvOI,1833
|
|
44
44
|
divi/extern/scipy/pyprima/common/redrho.py,sha256=J6rJILcOoCeo942LUAXxpUvKLarUGNCGdC-zcmIlVHE,1264
|
|
45
45
|
divi/extern/scipy/pyprima/common/selectx.py,sha256=mXVS2L6AuTmbOhpp1KlXwOBR54ttnbjwagYfnXhezJY,14713
|
|
46
|
-
divi/qprog/__init__.py,sha256=
|
|
46
|
+
divi/qprog/__init__.py,sha256=AkyI0JDBK4REYS_Z0op2sM81nFW6HEmqWJtfg6ARMJw,693
|
|
47
47
|
divi/qprog/algorithms/__init__.py,sha256=KLGD3zRk3z4nJQDqBjejTGgJ5m0n02jyBVHLJihMMws,355
|
|
48
|
-
divi/qprog/algorithms/_ansatze.py,sha256=
|
|
49
|
-
divi/qprog/algorithms/_qaoa.py,sha256=
|
|
50
|
-
divi/qprog/algorithms/_vqe.py,sha256=
|
|
51
|
-
divi/qprog/batch.py,sha256=
|
|
52
|
-
divi/qprog/
|
|
53
|
-
divi/qprog/
|
|
48
|
+
divi/qprog/algorithms/_ansatze.py,sha256=bc-8AtJhaM45iwA5LoTup2mxlecHlIgjia6gT5c5W6E,11422
|
|
49
|
+
divi/qprog/algorithms/_qaoa.py,sha256=uNqNxTyMvIyKRJ6uABiKq9H6g_FPN7Wxtn-LeoaxehU,20080
|
|
50
|
+
divi/qprog/algorithms/_vqe.py,sha256=_xbuhCI8BPwiULhH6SKSfz1noI1Z63u9WZC7ivNcCAI,12197
|
|
51
|
+
divi/qprog/batch.py,sha256=1EDkM4NFr_wjxjpdFNJpBufpylG6Bcg-9v_TaPR2vgQ,18605
|
|
52
|
+
divi/qprog/exceptions.py,sha256=2VvUf8qgNBw60Q4wyt_2nbE4JHHMmZiT2JaGmWChp2o,231
|
|
53
|
+
divi/qprog/optimizers.py,sha256=xw3KIIwWEGYSC_RnXCBARWvkHuzmKDmUt1wuRhrrIqg,17123
|
|
54
|
+
divi/qprog/quantum_program.py,sha256=Bvq_CWWc8gea9i4aQ36jw8rSDKR3jNgHnUqErSMfeDs,8767
|
|
55
|
+
divi/qprog/variational_quantum_algorithm.py,sha256=kohRUBKyrto04vJedR9uZC766Vcl6g9lSvtkI541a6Y,29433
|
|
54
56
|
divi/qprog/workflows/__init__.py,sha256=_GAFsZsgj9p61E1xUXasa1aspwcOWp4s8i6hA6mQ9eg,320
|
|
55
|
-
divi/qprog/workflows/_graph_partitioning.py,sha256=
|
|
56
|
-
divi/qprog/workflows/_qubo_partitioning.py,sha256=
|
|
57
|
-
divi/qprog/workflows/_vqe_sweep.py,sha256=
|
|
57
|
+
divi/qprog/workflows/_graph_partitioning.py,sha256=QvyxN50I1R3SkCMzZpjpdoXfDSC8eskY8tancRmTUF8,24217
|
|
58
|
+
divi/qprog/workflows/_qubo_partitioning.py,sha256=6_z095R6kFtuL8bHVQMCM7S8h4tTOQOqpthsqFzkaoQ,8248
|
|
59
|
+
divi/qprog/workflows/_vqe_sweep.py,sha256=l0dndM7jl9WUAZxF6sAd6Gnx37-vkBCNKpgZI07LR3s,19291
|
|
58
60
|
divi/reporting/__init__.py,sha256=gaBUZrhNxR53VHojZxfjvQRDl-eDHo901vLE8I95kIw,290
|
|
59
|
-
divi/reporting/_pbar.py,sha256=
|
|
60
|
-
divi/reporting/_qlogger.py,sha256=
|
|
61
|
-
divi/reporting/_reporter.py,sha256=
|
|
62
|
-
divi/utils.py,sha256=
|
|
63
|
-
qoro_divi-0.
|
|
64
|
-
qoro_divi-0.
|
|
65
|
-
qoro_divi-0.
|
|
66
|
-
qoro_divi-0.
|
|
67
|
-
qoro_divi-0.
|
|
68
|
-
qoro_divi-0.
|
|
61
|
+
divi/reporting/_pbar.py,sha256=I5UcriPLMKdTf_wusFCbxVH4MlA1Etui2GcYxRPC9Is,3686
|
|
62
|
+
divi/reporting/_qlogger.py,sha256=moFF9k_KECdhEmbsUTZHFXwVh30CuRCcChil_LBQUXM,5000
|
|
63
|
+
divi/reporting/_reporter.py,sha256=hqKWkpezolm80bJ16Tk4byjWxtZFEzgFAH9_yaXkQgM,2703
|
|
64
|
+
divi/utils.py,sha256=eOLcA7kY0Pib4pUsrfhN6l_GgNcKM95KVUSQLlh6W0s,7569
|
|
65
|
+
qoro_divi-0.4.0.dist-info/LICENSE,sha256=NS4JlQrgNwg1bvB3kE5shE-P4cJgnntgl-kClbOpG_Q,10760
|
|
66
|
+
qoro_divi-0.4.0.dist-info/LICENSES/.license-header,sha256=2jN_xtJscqP8LG-NaveY2KHUkfRCC543Y_XjOyKEfWY,105
|
|
67
|
+
qoro_divi-0.4.0.dist-info/LICENSES/Apache-2.0.txt,sha256=yoILHpvVuguUBpk8UwMnzJbcHUUyst9iGNNuEwUtWVc,10270
|
|
68
|
+
qoro_divi-0.4.0.dist-info/METADATA,sha256=TH0_pY9aljjQGcGnqabmavas03vLnhGXAam1vFq2SGU,2813
|
|
69
|
+
qoro_divi-0.4.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
|
70
|
+
qoro_divi-0.4.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|