qoro-divi 0.3.3__py3-none-any.whl → 0.3.4__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.

Files changed (69) hide show
  1. divi/__init__.py +1 -2
  2. divi/backends/__init__.py +7 -0
  3. divi/{parallel_simulator.py → backends/_parallel_simulator.py} +4 -3
  4. divi/{qoro_service.py → backends/_qoro_service.py} +5 -6
  5. divi/circuits/__init__.py +5 -0
  6. divi/{circuits.py → circuits/_core.py} +6 -20
  7. divi/{qasm.py → circuits/qasm.py} +2 -2
  8. divi/{exp → extern}/cirq/_validator.py +9 -7
  9. divi/qprog/__init__.py +18 -5
  10. divi/qprog/algorithms/__init__.py +14 -0
  11. divi/qprog/algorithms/_ansatze.py +215 -0
  12. divi/qprog/{_qaoa.py → algorithms/_qaoa.py} +1 -1
  13. divi/qprog/{_vqe.py → algorithms/_vqe.py} +29 -128
  14. divi/qprog/batch.py +2 -4
  15. divi/qprog/optimizers.py +1 -2
  16. divi/qprog/quantum_program.py +16 -9
  17. divi/qprog/workflows/__init__.py +10 -0
  18. divi/qprog/{_graph_partitioning.py → workflows/_graph_partitioning.py} +2 -2
  19. divi/qprog/{_qubo_partitioning.py → workflows/_qubo_partitioning.py} +2 -2
  20. divi/qprog/{_vqe_sweep.py → workflows/_vqe_sweep.py} +32 -20
  21. divi/reporting/__init__.py +7 -0
  22. divi/{qlogger.py → reporting/_qlogger.py} +2 -1
  23. divi/utils.py +14 -6
  24. {qoro_divi-0.3.3.dist-info → qoro_divi-0.3.4.dist-info}/METADATA +1 -1
  25. qoro_divi-0.3.4.dist-info/RECORD +68 -0
  26. qoro_divi-0.3.3.dist-info/RECORD +0 -62
  27. /divi/{interfaces.py → backends/_circuit_runner.py} +0 -0
  28. /divi/{qpu_system.py → backends/_qpu_system.py} +0 -0
  29. /divi/{qem.py → circuits/qem.py} +0 -0
  30. /divi/{exp → extern}/cirq/__init__.py +0 -0
  31. /divi/{exp → extern}/cirq/_lexer.py +0 -0
  32. /divi/{exp → extern}/cirq/_parser.py +0 -0
  33. /divi/{exp → extern}/cirq/_qasm_export.py +0 -0
  34. /divi/{exp → extern}/cirq/_qasm_import.py +0 -0
  35. /divi/{exp → extern}/cirq/exception.py +0 -0
  36. /divi/{exp → extern}/scipy/_cobyla.py +0 -0
  37. /divi/{exp → extern}/scipy/pyprima/LICENCE.txt +0 -0
  38. /divi/{exp → extern}/scipy/pyprima/__init__.py +0 -0
  39. /divi/{exp → extern}/scipy/pyprima/cobyla/__init__.py +0 -0
  40. /divi/{exp → extern}/scipy/pyprima/cobyla/cobyla.py +0 -0
  41. /divi/{exp → extern}/scipy/pyprima/cobyla/cobylb.py +0 -0
  42. /divi/{exp → extern}/scipy/pyprima/cobyla/geometry.py +0 -0
  43. /divi/{exp → extern}/scipy/pyprima/cobyla/initialize.py +0 -0
  44. /divi/{exp → extern}/scipy/pyprima/cobyla/trustregion.py +0 -0
  45. /divi/{exp → extern}/scipy/pyprima/cobyla/update.py +0 -0
  46. /divi/{exp → extern}/scipy/pyprima/common/__init__.py +0 -0
  47. /divi/{exp → extern}/scipy/pyprima/common/_bounds.py +0 -0
  48. /divi/{exp → extern}/scipy/pyprima/common/_linear_constraints.py +0 -0
  49. /divi/{exp → extern}/scipy/pyprima/common/_nonlinear_constraints.py +0 -0
  50. /divi/{exp → extern}/scipy/pyprima/common/_project.py +0 -0
  51. /divi/{exp → extern}/scipy/pyprima/common/checkbreak.py +0 -0
  52. /divi/{exp → extern}/scipy/pyprima/common/consts.py +0 -0
  53. /divi/{exp → extern}/scipy/pyprima/common/evaluate.py +0 -0
  54. /divi/{exp → extern}/scipy/pyprima/common/history.py +0 -0
  55. /divi/{exp → extern}/scipy/pyprima/common/infos.py +0 -0
  56. /divi/{exp → extern}/scipy/pyprima/common/linalg.py +0 -0
  57. /divi/{exp → extern}/scipy/pyprima/common/message.py +0 -0
  58. /divi/{exp → extern}/scipy/pyprima/common/powalg.py +0 -0
  59. /divi/{exp → extern}/scipy/pyprima/common/preproc.py +0 -0
  60. /divi/{exp → extern}/scipy/pyprima/common/present.py +0 -0
  61. /divi/{exp → extern}/scipy/pyprima/common/ratio.py +0 -0
  62. /divi/{exp → extern}/scipy/pyprima/common/redrho.py +0 -0
  63. /divi/{exp → extern}/scipy/pyprima/common/selectx.py +0 -0
  64. /divi/{_pbar.py → reporting/_pbar.py} +0 -0
  65. /divi/{reporter.py → reporting/_reporter.py} +0 -0
  66. {qoro_divi-0.3.3.dist-info → qoro_divi-0.3.4.dist-info}/LICENSE +0 -0
  67. {qoro_divi-0.3.3.dist-info → qoro_divi-0.3.4.dist-info}/LICENSES/.license-header +0 -0
  68. {qoro_divi-0.3.3.dist-info → qoro_divi-0.3.4.dist-info}/LICENSES/Apache-2.0.txt +0 -0
  69. {qoro_divi-0.3.3.dist-info → qoro_divi-0.3.4.dist-info}/WHEEL +0 -0
@@ -2,7 +2,6 @@
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
- from enum import Enum
6
5
  from warnings import warn
7
6
 
8
7
  import pennylane as qml
@@ -10,38 +9,10 @@ import sympy as sp
10
9
 
11
10
  from divi.circuits import MetaCircuit
12
11
  from divi.qprog import QuantumProgram
12
+ from divi.qprog.algorithms._ansatze import Ansatz, HartreeFockAnsatz
13
13
  from divi.qprog.optimizers import MonteCarloOptimizer, Optimizer
14
14
 
15
15
 
16
- class VQEAnsatz(Enum):
17
- UCCSD = "UCCSD"
18
- RY = "RY"
19
- RYRZ = "RYRZ"
20
- HW_EFFICIENT = "HW_EFFICIENT"
21
- QAOA = "QAOA"
22
- HARTREE_FOCK = "HF"
23
-
24
- def describe(self):
25
- return self.name, self.value
26
-
27
- def n_params(self, n_qubits, **kwargs):
28
- if self in (VQEAnsatz.UCCSD, VQEAnsatz.HARTREE_FOCK):
29
- singles, doubles = qml.qchem.excitations(
30
- kwargs.pop("n_electrons"), n_qubits
31
- )
32
- s_wires, d_wires = qml.qchem.excitations_to_wires(singles, doubles)
33
-
34
- return len(s_wires) + len(d_wires)
35
- elif self == VQEAnsatz.RY:
36
- return n_qubits
37
- elif self == VQEAnsatz.RYRZ:
38
- return 2 * n_qubits
39
- elif self == VQEAnsatz.HW_EFFICIENT:
40
- raise NotImplementedError
41
- elif self == VQEAnsatz.QAOA:
42
- return qml.QAOAEmbedding.shape(n_layers=1, n_wires=n_qubits)[1]
43
-
44
-
45
16
  class VQE(QuantumProgram):
46
17
  def __init__(
47
18
  self,
@@ -49,7 +20,7 @@ class VQE(QuantumProgram):
49
20
  molecule: qml.qchem.Molecule | None = None,
50
21
  n_electrons: int | None = None,
51
22
  n_layers: int = 1,
52
- ansatz=VQEAnsatz.HARTREE_FOCK,
23
+ ansatz: Ansatz | None = None,
53
24
  optimizer: Optimizer | None = None,
54
25
  max_iterations=10,
55
26
  **kwargs,
@@ -62,15 +33,15 @@ class VQE(QuantumProgram):
62
33
  molecule (pennylane.qchem.Molecule, optional): The molecule representing the problem.
63
34
  n_electrons (int, optional): Number of electrons associated with the Hamiltonian.
64
35
  Only needs to be provided when a Hamiltonian is given.
65
- ansatz (VQEAnsatz): The ansatz to use for the VQE problem
36
+ ansatz (Ansatz): The ansatz to use for the VQE problem
66
37
  optimizer (Optimizers): The optimizer to use.
67
38
  max_iterations (int): Maximum number of iteration optimizers.
68
39
  """
69
40
 
70
41
  # Local Variables
42
+ self.ansatz = HartreeFockAnsatz() if ansatz is None else ansatz
71
43
  self.n_layers = n_layers
72
44
  self.results = {}
73
- self.ansatz = ansatz
74
45
  self.max_iterations = max_iterations
75
46
  self.current_iteration = 0
76
47
 
@@ -84,6 +55,13 @@ class VQE(QuantumProgram):
84
55
 
85
56
  self._meta_circuits = self._create_meta_circuits_dict()
86
57
 
58
+ @property
59
+ def n_params(self):
60
+ return (
61
+ self.ansatz.n_params_per_layer(self.n_qubits, n_electrons=self.n_electrons)
62
+ * self.n_layers
63
+ )
64
+
87
65
  def _process_problem_input(self, hamiltonian, molecule, n_electrons):
88
66
  if hamiltonian is None and molecule is None:
89
67
  raise ValueError(
@@ -91,13 +69,8 @@ class VQE(QuantumProgram):
91
69
  )
92
70
 
93
71
  if hamiltonian is not None:
94
- if not isinstance(n_electrons, int) or n_electrons < 0:
95
- raise ValueError(
96
- f"`n_electrons` is expected to be a non-negative integer. Got {n_electrons}."
97
- )
98
-
99
- self.n_electrons = n_electrons
100
72
  self.n_qubits = len(hamiltonian.wires)
73
+ self.n_electrons = n_electrons
101
74
 
102
75
  if molecule is not None:
103
76
  self.molecule = molecule
@@ -112,10 +85,6 @@ class VQE(QuantumProgram):
112
85
  UserWarning,
113
86
  )
114
87
 
115
- self.n_params = self.ansatz.n_params(
116
- self.n_qubits, n_electrons=self.n_electrons
117
- )
118
-
119
88
  self.cost_hamiltonian = self._clean_hamiltonian(hamiltonian)
120
89
 
121
90
  def _clean_hamiltonian(
@@ -148,9 +117,17 @@ class VQE(QuantumProgram):
148
117
  return hamiltonian.simplify()
149
118
 
150
119
  def _create_meta_circuits_dict(self) -> dict[str, MetaCircuit]:
151
- weights_syms = sp.symarray("w", (self.n_layers, self.n_params))
120
+ weights_syms = sp.symarray(
121
+ "w",
122
+ (
123
+ self.n_layers,
124
+ self.ansatz.n_params_per_layer(
125
+ self.n_qubits, n_electrons=self.n_electrons
126
+ ),
127
+ ),
128
+ )
152
129
 
153
- def _prepare_circuit(ansatz, hamiltonian, params):
130
+ def _prepare_circuit(hamiltonian, params):
154
131
  """
155
132
  Prepare the circuit for the VQE problem.
156
133
  Args:
@@ -158,7 +135,12 @@ class VQE(QuantumProgram):
158
135
  hamiltonian (qml.Hamiltonian): The Hamiltonian to use
159
136
  params (list): The parameters to use for the ansatz
160
137
  """
161
- self._set_ansatz(ansatz, params)
138
+ self.ansatz.build(
139
+ params,
140
+ n_qubits=self.n_qubits,
141
+ n_layers=self.n_layers,
142
+ n_electrons=self.n_electrons,
143
+ )
162
144
 
163
145
  # Even though in principle we want to sample from a state,
164
146
  # we are applying an `expval` operation here to make it compatible
@@ -169,93 +151,12 @@ class VQE(QuantumProgram):
169
151
  return {
170
152
  "cost_circuit": self._meta_circuit_factory(
171
153
  qml.tape.make_qscript(_prepare_circuit)(
172
- self.ansatz, self.cost_hamiltonian, weights_syms
154
+ self.cost_hamiltonian, weights_syms
173
155
  ),
174
156
  symbols=weights_syms.flatten(),
175
157
  )
176
158
  }
177
159
 
178
- def _set_ansatz(self, ansatz: VQEAnsatz, params):
179
- """
180
- Set the ansatz for the VQE problem.
181
- Args:
182
- ansatz (Ansatze): The ansatz to use
183
- params (list): The parameters to use for the ansatz
184
- n_layers (int): The number of layers to use for the ansatz
185
- """
186
-
187
- def _add_hw_efficient_ansatz(params):
188
- raise NotImplementedError
189
-
190
- def _add_qaoa_ansatz(params):
191
- # This infers layers automatically from the parameters shape
192
- qml.QAOAEmbedding(
193
- features=[],
194
- weights=params.reshape(self.n_layers, -1),
195
- wires=range(self.n_qubits),
196
- )
197
-
198
- def _add_ry_ansatz(params):
199
- qml.layer(
200
- qml.AngleEmbedding,
201
- self.n_layers,
202
- params.reshape(self.n_layers, -1),
203
- wires=range(self.n_qubits),
204
- rotation="Y",
205
- )
206
-
207
- def _add_ryrz_ansatz(params):
208
- def _ryrz(params, wires):
209
- ry_rots, rz_rots = params.reshape(2, -1)
210
- qml.AngleEmbedding(ry_rots, wires=wires, rotation="Y")
211
- qml.AngleEmbedding(rz_rots, wires=wires, rotation="Z")
212
-
213
- qml.layer(
214
- _ryrz,
215
- self.n_layers,
216
- params.reshape(self.n_layers, -1),
217
- wires=range(self.n_qubits),
218
- )
219
-
220
- def _add_uccsd_ansatz(params):
221
- hf_state = qml.qchem.hf_state(self.n_electrons, self.n_qubits)
222
-
223
- singles, doubles = qml.qchem.excitations(self.n_electrons, self.n_qubits)
224
- s_wires, d_wires = qml.qchem.excitations_to_wires(singles, doubles)
225
-
226
- qml.UCCSD(
227
- params.reshape(self.n_layers, -1),
228
- wires=range(self.n_qubits),
229
- s_wires=s_wires,
230
- d_wires=d_wires,
231
- init_state=hf_state,
232
- n_repeats=self.n_layers,
233
- )
234
-
235
- def _add_hartree_fock_ansatz(params):
236
- singles, doubles = qml.qchem.excitations(self.n_electrons, self.n_qubits)
237
- hf_state = qml.qchem.hf_state(self.n_electrons, self.n_qubits)
238
-
239
- qml.layer(
240
- qml.AllSinglesDoubles,
241
- self.n_layers,
242
- params.reshape(self.n_layers, -1),
243
- wires=range(self.n_qubits),
244
- hf_state=hf_state,
245
- singles=singles,
246
- doubles=doubles,
247
- )
248
-
249
- # Reset the BasisState operations after the first layer
250
- # for behaviour similar to UCCSD ansatz
251
- for op in qml.QueuingManager.active_context().queue[1:]:
252
- op._hyperparameters["hf_state"] = 0
253
-
254
- if ansatz in VQEAnsatz:
255
- locals()[f"_add_{ansatz.name.lower()}_ansatz"](params)
256
- else:
257
- raise ValueError(f"Invalid Ansatz Value. Got {ansatz}.")
258
-
259
160
  def _generate_circuits(self):
260
161
  """
261
162
  Generate the circuits for the VQE problem.
divi/qprog/batch.py CHANGED
@@ -16,11 +16,9 @@ from warnings import warn
16
16
  from rich.console import Console
17
17
  from rich.progress import Progress, TaskID
18
18
 
19
- from divi._pbar import make_progress_bar
20
- from divi.interfaces import CircuitRunner
21
- from divi.parallel_simulator import ParallelSimulator
22
- from divi.qlogger import disable_logging
19
+ from divi.backends import CircuitRunner, ParallelSimulator
23
20
  from divi.qprog.quantum_program import QuantumProgram
21
+ from divi.reporting import disable_logging, make_progress_bar
24
22
 
25
23
 
26
24
  def queue_listener(
divi/qprog/optimizers.py CHANGED
@@ -5,12 +5,11 @@
5
5
  from abc import ABC, abstractmethod
6
6
  from collections.abc import Callable
7
7
  from enum import Enum
8
- from typing import Any
9
8
 
10
9
  import numpy as np
11
10
  from scipy.optimize import OptimizeResult, minimize
12
11
 
13
- from divi.exp.scipy._cobyla import _minimize_cobyla as cobyla_fn
12
+ from divi.extern.scipy._cobyla import _minimize_cobyla as cobyla_fn
14
13
 
15
14
 
16
15
  class ScipyMethod(Enum):
@@ -13,13 +13,11 @@ import numpy as np
13
13
  from pennylane.measurements import ExpectationMP
14
14
  from scipy.optimize import OptimizeResult
15
15
 
16
- from divi import QoroService
16
+ from divi.backends import CircuitRunner, JobStatus, QoroService
17
17
  from divi.circuits import Circuit, MetaCircuit
18
- from divi.interfaces import CircuitRunner
19
- from divi.qem import _NoMitigation
20
- from divi.qoro_service import JobStatus
18
+ from divi.circuits.qem import _NoMitigation
21
19
  from divi.qprog.optimizers import ScipyMethod, ScipyOptimizer
22
- from divi.reporter import LoggingProgressReporter, QueueProgressReporter
20
+ from divi.reporting import LoggingProgressReporter, QueueProgressReporter
23
21
 
24
22
  logger = logging.getLogger(__name__)
25
23
 
@@ -145,6 +143,10 @@ class QuantumProgram(ABC):
145
143
  def meta_circuits(self):
146
144
  return self._meta_circuits
147
145
 
146
+ @property
147
+ def n_params(self):
148
+ return self._n_params
149
+
148
150
  @abstractmethod
149
151
  def _create_meta_circuits_dict(self) -> dict[str, MetaCircuit]:
150
152
  pass
@@ -282,13 +284,18 @@ class QuantumProgram(ABC):
282
284
  for shots_dicts, curr_measurement_group in zip(
283
285
  shots_by_qem_idx, measurement_groups
284
286
  ):
287
+ if hasattr(self, "cost_hamiltonian"):
288
+ wire_order = tuple(reversed(self.cost_hamiltonian.wires))
289
+ else:
290
+ wire_order = tuple(
291
+ reversed(range(len(next(iter(shots_dicts[0].keys())))))
292
+ )
293
+
285
294
  curr_marginal_results = []
286
295
  for observable in curr_measurement_group:
296
+
287
297
  intermediate_exp_values = [
288
- ExpectationMP(observable).process_counts(
289
- shots_dict,
290
- tuple(reversed(range(len(next(iter(shots_dict.keys())))))),
291
- )
298
+ ExpectationMP(observable).process_counts(shots_dict, wire_order)
292
299
  for shots_dict in shots_dicts
293
300
  ]
294
301
 
@@ -0,0 +1,10 @@
1
+ # SPDX-FileCopyrightText: 2025 Qoro Quantum Ltd <divi@qoroquantum.de>
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from ._graph_partitioning import (
6
+ GraphPartitioningQAOA,
7
+ PartitioningConfig,
8
+ )
9
+ from ._qubo_partitioning import QUBOPartitioningQAOA
10
+ from ._vqe_sweep import MoleculeTransformer, VQEHyperparameterSweep
@@ -20,9 +20,9 @@ import scipy.sparse.linalg as spla
20
20
  from pymetis import part_graph
21
21
  from sklearn.cluster import SpectralClustering
22
22
 
23
- from divi.interfaces import CircuitRunner
23
+ from divi.backends import CircuitRunner
24
24
  from divi.qprog import QAOA, ProgramBatch, QuantumProgram
25
- from divi.qprog._qaoa import (
25
+ from divi.qprog.algorithms._qaoa import (
26
26
  _SUPPORTED_INITIAL_STATES_LITERAL,
27
27
  GraphProblem,
28
28
  GraphProblemTypes,
@@ -12,8 +12,8 @@ import numpy as np
12
12
  import scipy.sparse as sps
13
13
  from dimod import BinaryQuadraticModel
14
14
 
15
- from divi.interfaces import CircuitRunner
16
- from divi.qprog._qaoa import QAOA, QUBOProblemTypes
15
+ from divi.backends import CircuitRunner
16
+ from divi.qprog.algorithms import QAOA, QUBOProblemTypes
17
17
  from divi.qprog.batch import ProgramBatch
18
18
  from divi.qprog.optimizers import MonteCarloOptimizer, Optimizer
19
19
  from divi.qprog.quantum_program import QuantumProgram
@@ -14,7 +14,7 @@ import matplotlib.pyplot as plt
14
14
  import numpy as np
15
15
  import pennylane as qml
16
16
 
17
- from divi.qprog import VQE, ProgramBatch, VQEAnsatz
17
+ from divi.qprog import VQE, Ansatz, ProgramBatch
18
18
  from divi.qprog.optimizers import MonteCarloOptimizer, Optimizer
19
19
 
20
20
 
@@ -392,7 +392,7 @@ class VQEHyperparameterSweep(ProgramBatch):
392
392
 
393
393
  def __init__(
394
394
  self,
395
- ansatze: Sequence[VQEAnsatz],
395
+ ansatze: Sequence[Ansatz],
396
396
  molecule_transformer: MoleculeTransformer,
397
397
  optimizer: Optimizer | None = None,
398
398
  max_iterations: int = 10,
@@ -469,37 +469,49 @@ class VQEHyperparameterSweep(ProgramBatch):
469
469
  if self._executor is not None:
470
470
  self.join()
471
471
 
472
- data = []
473
- colors = ["blue", "g", "r", "c", "m", "y", "k"]
472
+ # Get the unique ansatz objects that were actually run
473
+ # Assumes `self.ansatze` is a list of the ansatz instances used.
474
+ unique_ansatze = self.ansatze
474
475
 
475
- ansatz_list = list(VQEAnsatz)
476
+ # Create a stable color mapping for each unique ansatz object
477
+ colors = ["blue", "g", "r", "c", "m", "y", "k"]
478
+ color_map = {
479
+ ansatz: colors[i % len(colors)] for i, ansatz in enumerate(unique_ansatze)
480
+ }
476
481
 
477
482
  if graph_type == "scatter":
478
- for ansatz, modifier in self.programs.keys():
483
+ # Plot each ansatz's results as a separate series for clarity
484
+ for ansatz in unique_ansatze:
485
+ modifiers = []
479
486
  min_energies = []
480
-
481
- curr_energies = self.programs[(ansatz, modifier)].losses[-1]
482
- min_energies.append(
483
- (
484
- modifier,
485
- min(curr_energies.values()),
486
- colors[ansatz_list.index(ansatz)],
487
- )
487
+ for modifier in self.molecule_transformer.bond_modifiers:
488
+ program_key = (ansatz, modifier)
489
+ if program_key in self.programs:
490
+ modifiers.append(modifier)
491
+ curr_energies = self.programs[program_key].losses[-1]
492
+ min_energies.append(min(curr_energies.values()))
493
+
494
+ # Use the new .name property for the label and the color_map
495
+ plt.scatter(
496
+ modifiers,
497
+ min_energies,
498
+ color=color_map[ansatz],
499
+ label=ansatz.name,
488
500
  )
489
- data.extend(min_energies)
490
-
491
- x, y, z = zip(*data)
492
- plt.scatter(x, y, color=z, label=ansatz)
493
501
 
494
502
  elif graph_type == "line":
495
- for ansatz in self.ansatze:
503
+ for ansatz in unique_ansatze:
496
504
  energies = []
497
505
  for modifier in self.molecule_transformer.bond_modifiers:
498
506
  energies.append(
499
507
  min(self.programs[(ansatz, modifier)].losses[-1].values())
500
508
  )
509
+
501
510
  plt.plot(
502
- self.molecule_transformer.bond_modifiers, energies, label=ansatz
511
+ self.molecule_transformer.bond_modifiers,
512
+ energies,
513
+ label=ansatz.name,
514
+ color=color_map[ansatz],
503
515
  )
504
516
 
505
517
  plt.xlabel(
@@ -0,0 +1,7 @@
1
+ # SPDX-FileCopyrightText: 2025 Qoro Quantum Ltd <divi@qoroquantum.de>
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from ._pbar import make_progress_bar
6
+ from ._qlogger import disable_logging, enable_logging
7
+ from ._reporter import LoggingProgressReporter, ProgressReporter, QueueProgressReporter
@@ -103,7 +103,8 @@ def enable_logging(level=logging.INFO):
103
103
  root_logger = logging.getLogger(__name__.split(".")[0])
104
104
 
105
105
  formatter = logging.Formatter(
106
- "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
106
+ "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
107
+ datefmt="%Y-%m-%d %H:%M:%S",
107
108
  )
108
109
 
109
110
  handler = OverwriteStreamHandler(sys.stdout)
divi/utils.py CHANGED
@@ -35,9 +35,10 @@ def convert_qubo_matrix_to_pennylane_ising(
35
35
  ) -> tuple[qml.operation.Operator, float]:
36
36
  """Convert QUBO matrix to Ising Hamiltonian in Pennylane.
37
37
 
38
- The conversion follows the mapping:
39
- - QUBO variables x_i ∈ {0,1} map to Ising variables s_i ∈ {-1,1} via s_i = 2x_i - 1
40
- - This transforms a QUBO problem into an equivalent Ising problem
38
+ The conversion follows the mapping from QUBO variables x_i ∈ {0,1} to
39
+ Ising variables σ_i ∈ {-1,1} via the transformation x_i = (1 - σ_i)/2. This
40
+ transforms a QUBO minimization problem into an equivalent Ising minimization
41
+ problem.
41
42
 
42
43
  Args:
43
44
  qubo_matrix: The QUBO matrix Q where the objective is to minimize x^T Q x
@@ -56,17 +57,24 @@ def convert_qubo_matrix_to_pennylane_ising(
56
57
  is_sparse = sps.issparse(qubo_matrix)
57
58
  backend = sps if is_sparse else np
58
59
 
60
+ symmetrized_qubo = (qubo_matrix + qubo_matrix.T) / 2
61
+
59
62
  # Gather non-zero indices in the upper triangle of the matrix
60
63
  triu_matrix = backend.triu(
61
- qubo_matrix,
64
+ symmetrized_qubo,
62
65
  **(
63
66
  {"format": qubo_matrix.format if qubo_matrix.format != "coo" else "csc"}
64
67
  if is_sparse
65
68
  else {}
66
69
  ),
67
70
  )
68
- rows, cols = triu_matrix.nonzero()
69
- values = triu_matrix[rows, cols].A1 if is_sparse else triu_matrix[rows, cols]
71
+
72
+ if is_sparse:
73
+ coo_mat = triu_matrix.tocoo()
74
+ rows, cols, values = coo_mat.row, coo_mat.col, coo_mat.data
75
+ else:
76
+ rows, cols = triu_matrix.nonzero()
77
+ values = triu_matrix[rows, cols]
70
78
 
71
79
  n = qubo_matrix.shape[0]
72
80
  linear_terms = np.zeros(n)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: qoro-divi
3
- Version: 0.3.3
3
+ Version: 0.3.4
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
@@ -0,0 +1,68 @@
1
+ divi/__init__.py,sha256=SyBWflbDS6qGEtHg-AfzD1TRNgfXoW2H5qTYGJ-W3XQ,167
2
+ divi/backends/__init__.py,sha256=1S3EJH5XXou2s7EnZowhfI4b3u3zLUG05x7etj4W-IM,264
3
+ divi/backends/_circuit_runner.py,sha256=P-8lekQIGwbhHv4ewfMFtKYIjmQHu7nmscwAmxsx72U,594
4
+ divi/backends/_parallel_simulator.py,sha256=jHt6C2-H65cYIMA0zc-gkSt69tNgaM98eXSRZqmI4UI,8979
5
+ divi/backends/_qoro_service.py,sha256=_x5CSkmcP_LFiqRdDax5vBcEJ7XRjtY6ZOfyPuwPn6U,14057
6
+ divi/backends/_qpu_system.py,sha256=teVeG18ukyzMFgbPSr4BLx4MJUHVK382RqZMOy2voFk,374
7
+ divi/circuits/__init__.py,sha256=Wl4BF0_TwG1Ol4oaftCD5lpkgS9us9EW7F4hu6r_eXM,151
8
+ divi/circuits/_core.py,sha256=TsCa7n1Gwd8thxn5JYF2rcKVnHFDXOD_8ZEwG749az4,4022
9
+ divi/circuits/qasm.py,sha256=5z_o4mY_eK24AXToFSugf74gTT_3iQuJddBZ7m5mvFU,7396
10
+ divi/circuits/qem.py,sha256=o6rMPUcxLuCBitBb8-QcxveUiKZVsP3HMamxyVFLi6M,6805
11
+ divi/extern/cirq/__init__.py,sha256=6NjP3TlQn_oNkg8VrKvEIoYQxB5Bx0mLLFOT3SXReTc,371
12
+ divi/extern/cirq/_lexer.py,sha256=x5UArrnN_JEyiq7E02ikq0wdmqZ2vEQ3_FADL1LIhQI,3187
13
+ divi/extern/cirq/_parser.py,sha256=z_bSn4m03-sfRlN8eL99Mo4LnjY-zmR-Xt6UrjzstZc,29279
14
+ divi/extern/cirq/_qasm_export.py,sha256=8C5xLYvIIkQTWWAAYo7ZjwtQjvYXNSflbf5UyUx6YUE,1024
15
+ divi/extern/cirq/_qasm_import.py,sha256=HbehrgfLl3iDdRyWr4o26Bek3ZpN-_dvNVSexl5-aVE,969
16
+ divi/extern/cirq/_validator.py,sha256=GVCeoi3IGUCPcqmg6E7lPtD52h-63_0AH4-MToajL4o,20509
17
+ divi/extern/cirq/exception.py,sha256=w1w2vSubOGMRmyKBFqXejxfeIAzkPZ6V7gSrDX_ap4A,765
18
+ divi/extern/scipy/_cobyla.py,sha256=cnCf5AsOM8JWIMiujuUbWMNOgmUr3ZET9y04hUyumHs,10937
19
+ divi/extern/scipy/pyprima/LICENCE.txt,sha256=mXN5ssG_U6OR0v0yldznW_PJTtKNZIgu3jDRtRjLDdY,1533
20
+ divi/extern/scipy/pyprima/__init__.py,sha256=WHV_bPKPLakKdP2TdecrbtMrZ7KR3qb1E3m5VkCjLSo,8956
21
+ divi/extern/scipy/pyprima/cobyla/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ divi/extern/scipy/pyprima/cobyla/cobyla.py,sha256=zIHjhLDkzhijMrzypObgYjQQfelUdxp6VOKQd34m_oU,22281
23
+ divi/extern/scipy/pyprima/cobyla/cobylb.py,sha256=DhOW4SnJ8ihLHybC4-1BK2X-5BFZlndEduuagmXQOVY,42091
24
+ divi/extern/scipy/pyprima/cobyla/geometry.py,sha256=YtGsY-lXAKmsuBj_D59H97Z8acDl7fAJGt4QTEigsiU,10789
25
+ divi/extern/scipy/pyprima/cobyla/initialize.py,sha256=QT9rpkO8IjlljA-z5wPxg7KFWtB_ae38Z7Ww0S-fMpU,9964
26
+ divi/extern/scipy/pyprima/cobyla/trustregion.py,sha256=AD_tdF7VCt6xBrduv0KFr7VgyUoGdIIz4mwde_9dk0g,26021
27
+ divi/extern/scipy/pyprima/cobyla/update.py,sha256=VuwqaE3wXxsGopPAkOAATmesLDUH-8WZrw3iRqu3jzs,14353
28
+ divi/extern/scipy/pyprima/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
+ divi/extern/scipy/pyprima/common/_bounds.py,sha256=0tY542ERqX53I5lreyVUy9XVXfNFvt1bx9peKM70U3U,1683
30
+ divi/extern/scipy/pyprima/common/_linear_constraints.py,sha256=piTatWAMPQo-nwFB14VpRQ6JphBgrBL8OjLysBrTlhI,2160
31
+ divi/extern/scipy/pyprima/common/_nonlinear_constraints.py,sha256=evfY-4FWXKcGae658NXfrlSpCtkHRxCqSG-MyO-WDx4,2180
32
+ divi/extern/scipy/pyprima/common/_project.py,sha256=dnQURl2ztxjGDvoYgMZGnEqUGLUoNUvBaLS12p9-qN0,8541
33
+ divi/extern/scipy/pyprima/common/checkbreak.py,sha256=WrW_dAjZI_3iKvvG3eLTJCxcj5HkIksUBtQQ9BUdB_E,3549
34
+ divi/extern/scipy/pyprima/common/consts.py,sha256=PiGCfDRy9fZjmGJBeCg25gULDfe1cv2HkjS6CQujphg,1313
35
+ divi/extern/scipy/pyprima/common/evaluate.py,sha256=vzjNPdGiAFdD8qpUVp_V1b5f3t2pFyr2N-sMSnTE6OI,3156
36
+ divi/extern/scipy/pyprima/common/history.py,sha256=m0cQ7VOGefWWKTPweqx3dvGZiyzGClTB0BjaKY5mOtQ,1362
37
+ divi/extern/scipy/pyprima/common/infos.py,sha256=MzhS3XciMW5fg4ccW8ubZ3Mkdp2qT6sq56GAkYZikXI,704
38
+ divi/extern/scipy/pyprima/common/linalg.py,sha256=HYoy6vYR2AMUVGSKbA8xj9tjvloMofk_s26N34qiFNk,14516
39
+ divi/extern/scipy/pyprima/common/message.py,sha256=G2_hmqxKvZg0aGCXqw3VmXDxrle8k0Grujzb4iiuPLI,10086
40
+ divi/extern/scipy/pyprima/common/powalg.py,sha256=Azla5UC3oPppDcSTub_1auLS_QXQ_aY1Djm4RT3HkV4,6825
41
+ divi/extern/scipy/pyprima/common/preproc.py,sha256=Ye62rhEilf3ah9aiGc6cSLZg77_qAi3FPK2r4XvPxGk,14929
42
+ divi/extern/scipy/pyprima/common/present.py,sha256=caedmqSB5ggGXNfky0A6v6FAdyaEGrbMEJqNh5Cf6l4,147
43
+ divi/extern/scipy/pyprima/common/ratio.py,sha256=taadehpW0c3ULUggH5frIMpvTom53dsEhvFaXrIKvOI,1833
44
+ divi/extern/scipy/pyprima/common/redrho.py,sha256=J6rJILcOoCeo942LUAXxpUvKLarUGNCGdC-zcmIlVHE,1264
45
+ divi/extern/scipy/pyprima/common/selectx.py,sha256=mXVS2L6AuTmbOhpp1KlXwOBR54ttnbjwagYfnXhezJY,14713
46
+ divi/qprog/__init__.py,sha256=3X7MK7PjXI-rCZQ9OYq314w14npmasCNSBECq23DW7U,622
47
+ divi/qprog/algorithms/__init__.py,sha256=KLGD3zRk3z4nJQDqBjejTGgJ5m0n02jyBVHLJihMMws,355
48
+ divi/qprog/algorithms/_ansatze.py,sha256=ATep35g7CD_t7wrmW62g5a8_XbXkbwwjU8Y4Poux4qA,7933
49
+ divi/qprog/algorithms/_qaoa.py,sha256=cGYE0xkO7sBfqVyO5HxJNWi9-Vu84eTjJEGcIfbwweg,15951
50
+ divi/qprog/algorithms/_vqe.py,sha256=FE0lnX_WKgKJnARdMvzehlLgmXgfBwGapf-fGCiIqMI,6499
51
+ divi/qprog/batch.py,sha256=F_s83FDqnbm7UAYeTizKQqNysE6bACTorwtv8hmcJm4,10036
52
+ divi/qprog/optimizers.py,sha256=SYWknntCl_QI4icoVdFvunxY5rZ2S0GGBVvtIWypk30,6433
53
+ divi/qprog/quantum_program.py,sha256=2q4SDZ9TwTu_HdqNr3EWRNXBLlFEGSSWdHoUyAljT_c,14978
54
+ divi/qprog/workflows/__init__.py,sha256=_GAFsZsgj9p61E1xUXasa1aspwcOWp4s8i6hA6mQ9eg,320
55
+ divi/qprog/workflows/_graph_partitioning.py,sha256=Y_LpQy9djbeXplVmyfr2E2aWjmwkM0GY7xU2N8hJhYY,23675
56
+ divi/qprog/workflows/_qubo_partitioning.py,sha256=3IFD_N2vjwaFuK155fg26rbrGyYqEjzEnkxlw2BqRF0,7473
57
+ divi/qprog/workflows/_vqe_sweep.py,sha256=eoontmK1z0KTdkEW2TbfCs9UKI4ThlFYXAivpO9GWK4,17974
58
+ divi/reporting/__init__.py,sha256=gaBUZrhNxR53VHojZxfjvQRDl-eDHo901vLE8I95kIw,290
59
+ divi/reporting/_pbar.py,sha256=I8AWI93mpcJXIXTIvsa3JghazO65Pmrq-bW2bJTf2Ik,2131
60
+ divi/reporting/_qlogger.py,sha256=hZ6hELP5Z41P1KpJV9xZ0TuHeI0ztswpcZrJ4yHKdAg,3860
61
+ divi/reporting/_reporter.py,sha256=AgB2Mno1sIXF-VhOi8i-LGuWG5FMG1HelMw5cMc84HM,2977
62
+ divi/utils.py,sha256=txdkb2y_z99-ysxdmC3Rl3tw0hkJsvRltLybCXb89bA,3816
63
+ qoro_divi-0.3.4.dist-info/LICENSE,sha256=NS4JlQrgNwg1bvB3kE5shE-P4cJgnntgl-kClbOpG_Q,10760
64
+ qoro_divi-0.3.4.dist-info/LICENSES/.license-header,sha256=2jN_xtJscqP8LG-NaveY2KHUkfRCC543Y_XjOyKEfWY,105
65
+ qoro_divi-0.3.4.dist-info/LICENSES/Apache-2.0.txt,sha256=yoILHpvVuguUBpk8UwMnzJbcHUUyst9iGNNuEwUtWVc,10270
66
+ qoro_divi-0.3.4.dist-info/METADATA,sha256=Or34jlJGk7jDChjEGjpE__8zaX58jlxCF9-MjBHpK-w,2428
67
+ qoro_divi-0.3.4.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
68
+ qoro_divi-0.3.4.dist-info/RECORD,,
@@ -1,62 +0,0 @@
1
- divi/__init__.py,sha256=WNAlzdjio0M5la_NTGk4-0AFqItI6HEBExRs6ck9j0Y,203
2
- divi/_pbar.py,sha256=I8AWI93mpcJXIXTIvsa3JghazO65Pmrq-bW2bJTf2Ik,2131
3
- divi/circuits.py,sha256=OKcwTMXIvCIjvpLvdeQBWGYElcVUNNyA3z8yXnxUXeo,4476
4
- divi/exp/cirq/__init__.py,sha256=6NjP3TlQn_oNkg8VrKvEIoYQxB5Bx0mLLFOT3SXReTc,371
5
- divi/exp/cirq/_lexer.py,sha256=x5UArrnN_JEyiq7E02ikq0wdmqZ2vEQ3_FADL1LIhQI,3187
6
- divi/exp/cirq/_parser.py,sha256=z_bSn4m03-sfRlN8eL99Mo4LnjY-zmR-Xt6UrjzstZc,29279
7
- divi/exp/cirq/_qasm_export.py,sha256=8C5xLYvIIkQTWWAAYo7ZjwtQjvYXNSflbf5UyUx6YUE,1024
8
- divi/exp/cirq/_qasm_import.py,sha256=HbehrgfLl3iDdRyWr4o26Bek3ZpN-_dvNVSexl5-aVE,969
9
- divi/exp/cirq/_validator.py,sha256=552fiXRpiuXc6aoNNXjnv6SWWCAdBAKieQEOTfCQy1s,20484
10
- divi/exp/cirq/exception.py,sha256=w1w2vSubOGMRmyKBFqXejxfeIAzkPZ6V7gSrDX_ap4A,765
11
- divi/exp/scipy/_cobyla.py,sha256=cnCf5AsOM8JWIMiujuUbWMNOgmUr3ZET9y04hUyumHs,10937
12
- divi/exp/scipy/pyprima/LICENCE.txt,sha256=mXN5ssG_U6OR0v0yldznW_PJTtKNZIgu3jDRtRjLDdY,1533
13
- divi/exp/scipy/pyprima/__init__.py,sha256=WHV_bPKPLakKdP2TdecrbtMrZ7KR3qb1E3m5VkCjLSo,8956
14
- divi/exp/scipy/pyprima/cobyla/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- divi/exp/scipy/pyprima/cobyla/cobyla.py,sha256=zIHjhLDkzhijMrzypObgYjQQfelUdxp6VOKQd34m_oU,22281
16
- divi/exp/scipy/pyprima/cobyla/cobylb.py,sha256=DhOW4SnJ8ihLHybC4-1BK2X-5BFZlndEduuagmXQOVY,42091
17
- divi/exp/scipy/pyprima/cobyla/geometry.py,sha256=YtGsY-lXAKmsuBj_D59H97Z8acDl7fAJGt4QTEigsiU,10789
18
- divi/exp/scipy/pyprima/cobyla/initialize.py,sha256=QT9rpkO8IjlljA-z5wPxg7KFWtB_ae38Z7Ww0S-fMpU,9964
19
- divi/exp/scipy/pyprima/cobyla/trustregion.py,sha256=AD_tdF7VCt6xBrduv0KFr7VgyUoGdIIz4mwde_9dk0g,26021
20
- divi/exp/scipy/pyprima/cobyla/update.py,sha256=VuwqaE3wXxsGopPAkOAATmesLDUH-8WZrw3iRqu3jzs,14353
21
- divi/exp/scipy/pyprima/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
- divi/exp/scipy/pyprima/common/_bounds.py,sha256=0tY542ERqX53I5lreyVUy9XVXfNFvt1bx9peKM70U3U,1683
23
- divi/exp/scipy/pyprima/common/_linear_constraints.py,sha256=piTatWAMPQo-nwFB14VpRQ6JphBgrBL8OjLysBrTlhI,2160
24
- divi/exp/scipy/pyprima/common/_nonlinear_constraints.py,sha256=evfY-4FWXKcGae658NXfrlSpCtkHRxCqSG-MyO-WDx4,2180
25
- divi/exp/scipy/pyprima/common/_project.py,sha256=dnQURl2ztxjGDvoYgMZGnEqUGLUoNUvBaLS12p9-qN0,8541
26
- divi/exp/scipy/pyprima/common/checkbreak.py,sha256=WrW_dAjZI_3iKvvG3eLTJCxcj5HkIksUBtQQ9BUdB_E,3549
27
- divi/exp/scipy/pyprima/common/consts.py,sha256=PiGCfDRy9fZjmGJBeCg25gULDfe1cv2HkjS6CQujphg,1313
28
- divi/exp/scipy/pyprima/common/evaluate.py,sha256=vzjNPdGiAFdD8qpUVp_V1b5f3t2pFyr2N-sMSnTE6OI,3156
29
- divi/exp/scipy/pyprima/common/history.py,sha256=m0cQ7VOGefWWKTPweqx3dvGZiyzGClTB0BjaKY5mOtQ,1362
30
- divi/exp/scipy/pyprima/common/infos.py,sha256=MzhS3XciMW5fg4ccW8ubZ3Mkdp2qT6sq56GAkYZikXI,704
31
- divi/exp/scipy/pyprima/common/linalg.py,sha256=HYoy6vYR2AMUVGSKbA8xj9tjvloMofk_s26N34qiFNk,14516
32
- divi/exp/scipy/pyprima/common/message.py,sha256=G2_hmqxKvZg0aGCXqw3VmXDxrle8k0Grujzb4iiuPLI,10086
33
- divi/exp/scipy/pyprima/common/powalg.py,sha256=Azla5UC3oPppDcSTub_1auLS_QXQ_aY1Djm4RT3HkV4,6825
34
- divi/exp/scipy/pyprima/common/preproc.py,sha256=Ye62rhEilf3ah9aiGc6cSLZg77_qAi3FPK2r4XvPxGk,14929
35
- divi/exp/scipy/pyprima/common/present.py,sha256=caedmqSB5ggGXNfky0A6v6FAdyaEGrbMEJqNh5Cf6l4,147
36
- divi/exp/scipy/pyprima/common/ratio.py,sha256=taadehpW0c3ULUggH5frIMpvTom53dsEhvFaXrIKvOI,1833
37
- divi/exp/scipy/pyprima/common/redrho.py,sha256=J6rJILcOoCeo942LUAXxpUvKLarUGNCGdC-zcmIlVHE,1264
38
- divi/exp/scipy/pyprima/common/selectx.py,sha256=mXVS2L6AuTmbOhpp1KlXwOBR54ttnbjwagYfnXhezJY,14713
39
- divi/interfaces.py,sha256=P-8lekQIGwbhHv4ewfMFtKYIjmQHu7nmscwAmxsx72U,594
40
- divi/parallel_simulator.py,sha256=2JCwmootXLtDplplEqtykKc8HiYe6G0zKWemIb-IIdE,8947
41
- divi/qasm.py,sha256=lfWky4E9qetotVo8BII58svutVVZEV14BntoC14bo40,7384
42
- divi/qem.py,sha256=o6rMPUcxLuCBitBb8-QcxveUiKZVsP3HMamxyVFLi6M,6805
43
- divi/qlogger.py,sha256=TcZMaNZXDHguKJGLD6t2bEmP25rkRQVaSS8FLs9U-lI,3822
44
- divi/qoro_service.py,sha256=CASWEE6ySlFeQ6pHeOZJUUuwnldEVsPakn_4jTFPnX0,14087
45
- divi/qprog/__init__.py,sha256=av3I0i3VldwblycfQjcXcJHGVY1m05rnsZ0R5iGMCwk,546
46
- divi/qprog/_graph_partitioning.py,sha256=cYeHQ2VJAeOzooO43dPfWdXjRZPF_UmHR_H2D7VIpnU,23666
47
- divi/qprog/_qaoa.py,sha256=Cq1AnaS386iGEv8OiHhSkyGkMG1MwfX3_mq2jBXavgI,15950
48
- divi/qprog/_qubo_partitioning.py,sha256=h2QPDm1pzNYzsrvw0WZ04fb-nOzj8xFqf5YZqOU5FHk,7470
49
- divi/qprog/_vqe.py,sha256=21KVvf40UGwxuJQ0OJ1YuiFctvEVbJRklilpxgopnkA,10069
50
- divi/qprog/_vqe_sweep.py,sha256=T5tXVOENn4VlzwUxSR0SGbv1EWVRdy4H9m1M_sLElCk,17286
51
- divi/qprog/batch.py,sha256=jxeOO5xFecCCmA82GDAtg3mA8PeW_c5O5ooqEcb2-Bg,10093
52
- divi/qprog/optimizers.py,sha256=sbOxd9VgMroZn1llN5wyIMLEM-a4x_YKJpt34ApaKX8,6453
53
- divi/qprog/quantum_program.py,sha256=D2L1zjvW_G3O0oNgty3Y_QhIGrJz0V4rzcz6VSoXFME,14779
54
- divi/qpu_system.py,sha256=teVeG18ukyzMFgbPSr4BLx4MJUHVK382RqZMOy2voFk,374
55
- divi/reporter.py,sha256=AgB2Mno1sIXF-VhOi8i-LGuWG5FMG1HelMw5cMc84HM,2977
56
- divi/utils.py,sha256=EEyGakoz33AvU0Rq7iijL8AULMg4FGcGBtmOlpSw-tY,3603
57
- qoro_divi-0.3.3.dist-info/LICENSE,sha256=NS4JlQrgNwg1bvB3kE5shE-P4cJgnntgl-kClbOpG_Q,10760
58
- qoro_divi-0.3.3.dist-info/LICENSES/.license-header,sha256=2jN_xtJscqP8LG-NaveY2KHUkfRCC543Y_XjOyKEfWY,105
59
- qoro_divi-0.3.3.dist-info/LICENSES/Apache-2.0.txt,sha256=yoILHpvVuguUBpk8UwMnzJbcHUUyst9iGNNuEwUtWVc,10270
60
- qoro_divi-0.3.3.dist-info/METADATA,sha256=txN4vgtVVbI_PuH1vtN70jRHY21S7WL35Bj1eFOxgBA,2428
61
- qoro_divi-0.3.3.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
62
- qoro_divi-0.3.3.dist-info/RECORD,,
File without changes
File without changes
File without changes
File without changes