eqc-models 0.10.0__py3-none-any.whl → 0.10.3__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.
Files changed (69) hide show
  1. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/__init__.py +2 -1
  2. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/algorithms/penaltymultiplier.py +20 -7
  3. eqc_models-0.10.3.data/platlib/eqc_models/assignment/setpartition.py +4 -0
  4. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/base/base.py +44 -4
  5. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/base/polyeval.c +163 -163
  6. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/base/polyeval.cpython-310-darwin.so +0 -0
  7. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/base/polynomial.py +7 -3
  8. eqc_models-0.10.3.data/platlib/eqc_models/combinatorics/__init__.py +6 -0
  9. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/combinatorics/setcover.py +35 -17
  10. {eqc_models-0.10.0.data/platlib/eqc_models/assignment → eqc_models-0.10.3.data/platlib/eqc_models/combinatorics}/setpartition.py +2 -0
  11. eqc_models-0.10.3.data/platlib/eqc_models/graph/__init__.py +6 -0
  12. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/graph/maxkcut.py +26 -68
  13. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/solvers/qciclient.py +11 -2
  14. {eqc_models-0.10.0.dist-info → eqc_models-0.10.3.dist-info}/METADATA +3 -2
  15. eqc_models-0.10.3.dist-info/RECORD +59 -0
  16. {eqc_models-0.10.0.dist-info → eqc_models-0.10.3.dist-info}/WHEEL +1 -1
  17. eqc_models-0.10.0.data/platlib/eqc_models/base.py +0 -115
  18. eqc_models-0.10.0.data/platlib/eqc_models/communitydetection.py +0 -25
  19. eqc_models-0.10.0.data/platlib/eqc_models/eqcdirectsolver.py +0 -61
  20. eqc_models-0.10.0.data/platlib/eqc_models/graph/__init__.py +0 -5
  21. eqc_models-0.10.0.data/platlib/eqc_models/graphs.py +0 -28
  22. eqc_models-0.10.0.data/platlib/eqc_models/maxcut.py +0 -113
  23. eqc_models-0.10.0.data/platlib/eqc_models/maxkcut.py +0 -185
  24. eqc_models-0.10.0.data/platlib/eqc_models/quadraticmodel.py +0 -131
  25. eqc_models-0.10.0.data/platlib/eqc_models/solvers/eqcdirect.py +0 -160
  26. eqc_models-0.10.0.dist-info/RECORD +0 -65
  27. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/compile_extensions.py +0 -0
  28. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/algorithms/__init__.py +0 -0
  29. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/algorithms/base.py +0 -0
  30. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/allocation/__init__.py +0 -0
  31. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/allocation/allocation.py +0 -0
  32. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/allocation/portbase.py +0 -0
  33. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/allocation/portmomentum.py +0 -0
  34. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/assignment/__init__.py +0 -0
  35. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/assignment/qap.py +0 -0
  36. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/base/__init__.py +0 -0
  37. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/base/constraints.py +0 -0
  38. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/base/operators.py +0 -0
  39. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/base/polyeval.pyx +0 -0
  40. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/base/quadratic.py +0 -0
  41. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/decoding.py +0 -0
  42. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/graph/base.py +0 -0
  43. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/graph/hypergraph.py +0 -0
  44. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/graph/maxcut.py +0 -0
  45. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/graph/partition.py +0 -0
  46. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/ml/__init__.py +0 -0
  47. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/ml/classifierbase.py +0 -0
  48. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/ml/classifierqboost.py +0 -0
  49. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/ml/classifierqsvm.py +0 -0
  50. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/ml/clustering.py +0 -0
  51. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/ml/clusteringbase.py +0 -0
  52. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/ml/cvqboost_hamiltonian.pyx +0 -0
  53. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/ml/cvqboost_hamiltonian_c_func.c +0 -0
  54. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/ml/cvqboost_hamiltonian_c_func.h +0 -0
  55. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/ml/decomposition.py +0 -0
  56. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/ml/forecast.py +0 -0
  57. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/ml/forecastbase.py +0 -0
  58. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/ml/regressor.py +0 -0
  59. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/ml/regressorbase.py +0 -0
  60. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/ml/reservoir.py +0 -0
  61. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/sequence/__init__.py +0 -0
  62. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/sequence/tsp.py +0 -0
  63. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/solvers/__init__.py +0 -0
  64. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/utilities/__init__.py +0 -0
  65. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/utilities/fileio.py +0 -0
  66. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/utilities/polynomial.py +0 -0
  67. {eqc_models-0.10.0.data → eqc_models-0.10.3.data}/platlib/eqc_models/utilities/qplib.py +0 -0
  68. {eqc_models-0.10.0.dist-info → eqc_models-0.10.3.dist-info/licenses}/LICENSE.txt +0 -0
  69. {eqc_models-0.10.0.dist-info → eqc_models-0.10.3.dist-info}/top_level.txt +0 -0
@@ -117,12 +117,15 @@ class PolynomialModel(PolynomialMixin, EqcModel):
117
117
 
118
118
  @property
119
119
  def qubo(self) -> QUBO:
120
+ polynomial = self.polynomial
121
+ coefficients = polynomial.coefficients
122
+ indices = polynomial.indices
120
123
  try:
121
- if np.all([len(self.polynomial.indices[i]) == 2 for i in range(len(self.polynomial.indices))]):
124
+ if np.all([len(indices[i]) == 2 for i in range(len(indices))]):
122
125
  bin_n = 0
123
126
  bits = []
124
- C, J = self._quadratic_polynomial_to_qubo_coefficients(self.polynomial.coefficients,
125
- self.polynomial.indices, self.n)
127
+ C, J = self._quadratic_polynomial_to_qubo_coefficients(coefficients,
128
+ indices, self.n)
126
129
  # upper_bound is an array of the maximum values each variable can take
127
130
  upper_bound = self.upper_bound
128
131
  if np.sum(upper_bound) != upper_bound.shape[0]:
@@ -158,6 +161,7 @@ class PolynomialModel(PolynomialMixin, EqcModel):
158
161
  raise OperatorNotAvailableError("QUBO operator not available")
159
162
  except OperatorNotAvailableError as e:
160
163
  print(e)
164
+ raise
161
165
 
162
166
  def _quadratic_polynomial_to_qubo_coefficients(self, coefficients, indices, num_variables):
163
167
  """
@@ -0,0 +1,6 @@
1
+ # (C) Quantum Computing Inc., 2024.
2
+
3
+ from .setcover import SetCoverModel
4
+ from .setpartition import SetPartitionModel
5
+
6
+ __all__ = ["SetCoverModel", "SetPartitionModel"]
@@ -37,44 +37,61 @@ class SetCoverModel(ConstrainedQuadraticModel):
37
37
  List of weights where each weight is the cost of choosing the subset
38
38
  corresponding to the index of the weight.
39
39
 
40
+
40
41
  >>> X = [set(['A', 'B']), set(['B', 'C']), set(['C'])]
41
42
  >>> weights = [2, 2, 1]
42
43
  >>> model = SetCoverModel(X, weights)
43
- >>> model.penalty_multiplier = 2
44
+ >>> model.penalty_multiplier = 8
45
+ >>> lhs, rhs = model.constraints
46
+ >>> lhs
47
+ array([[ 1, 0, 0, 0, 0],
48
+ [ 1, 1, 0, -1, 0],
49
+ [ 0, 1, 1, 0, -1]])
44
50
  >>> from eqc_models.solvers import Dirac3IntegerCloudSolver
45
51
  >>> solver = Dirac3IntegerCloudSolver()
46
52
  >>> response = solver.solve(model, relaxation_schedule=1, num_samples=5) #doctest: +ELLIPSIS
47
53
  20...
48
54
  >>> solutions = response["results"]["solutions"]
49
55
  >>> solutions[0]
50
- [1, 0, 1, 0, 0, 0]
51
- >>> model.decode(solutions[0])
52
- [{'B', 'A'}, {'C'}]
56
+ [1, 0, 1, 0, 0]
57
+ >>> selections = model.decode(solutions[0])
58
+ >>> assert {'B', 'A'} in selections
59
+ >>> assert {'C'} in selections
60
+ >>> assert len(selections) == 2
53
61
 
54
62
  """
55
63
 
56
64
  def __init__(self, subsets, weights):
57
65
  # ensure that X is ordered
58
- self.X = X = list(subsets)
59
- self.S = S = set()
66
+ self.S = S = list(subsets)
67
+ self.universal_set = U = set()
60
68
 
61
69
  for x in subsets:
62
- S = S.union(x)
70
+ U.update(x)
63
71
  # elements is sorted to maintain consistent output
64
- elements = [a for a in S]
72
+ elements = [a for a in U]
65
73
  elements.sort()
66
74
  # constraints
67
75
  A = []
68
76
  b = []
69
- variables = [f'x_{i}' for i in range(len(X))]
77
+ variables = [f'x_{i}' for i in range(len(S))]
70
78
  pos = 0
79
+ num_slacks = 0
80
+ slack_ub = []
71
81
  for a in elements:
72
- variables.append(f"s_{pos}")
73
- constraint = [1 if a in X[i] else 0 for i in range(len(X))]
74
- slacks = [0 for i in range(len(S))]
75
- slacks[pos] = -1
82
+ num_sets = sum([1 if a in S[i] else 0 for i in range(len(S))])
83
+ assert num_sets >= 1, "Invalid subsets, check the universal set"
84
+ if num_sets > 1:
85
+ num_slacks += 1
86
+ slack_ub.append(num_sets-1)
87
+ for i, a in enumerate(elements):
88
+ constraint = [1 if a in S[j] else 0 for j in range(len(S))]
89
+ slacks = [0 for i in range(num_slacks)]
90
+ if slack_ub[i] > 0:
91
+ variables.append(f"s_{pos}")
92
+ slacks[pos] = -1
93
+ pos += 1
76
94
  A.append(constraint + slacks)
77
- pos += 1
78
95
  b.append(1)
79
96
  n = len(variables)
80
97
  J = np.zeros((n, n))
@@ -83,11 +100,12 @@ class SetCoverModel(ConstrainedQuadraticModel):
83
100
  # call the superclass constructor with the objective and constraints
84
101
  super(SetCoverModel, self).__init__(h, J, np.array(A), np.array(b))
85
102
  # set upper bound on the variables to be 1 for x_i and the length of X minus 1 for the slacks
86
- self.upper_bound = np.array([1 for i in range(len(weights))] + [len(X)-1 for i in range(n-len(weights))])
103
+ slack_ub = [val for val in slack_ub if val > 0]
104
+ self.upper_bound = np.array([1 for i in range(len(weights))] + slack_ub)
87
105
 
88
106
  def decode(self, solution) -> List:
89
107
  xbar = []
90
- for i in range(len(self.X)):
108
+ for i in range(len(self.S)):
91
109
  if solution[i] > 0.5:
92
- xbar.append(self.X[i])
110
+ xbar.append(self.S[i])
93
111
  return xbar
@@ -86,6 +86,8 @@ class SetPartitionModel(ConstrainedPolynomialModel):
86
86
  b = np.ones((A.shape[0],))
87
87
  n = A.shape[1]
88
88
 
89
+ self.upper_bound = np.ones((n,), np.int32)
90
+
89
91
  # Define the linear objective function based on subset weights
90
92
  self.linear_objective = np.array(weights).reshape((n, 1))
91
93
  self.quad_objective = np.zeros((n, n)) #np.zeros_like(J)
@@ -0,0 +1,6 @@
1
+ # (C) Quantum Computing Inc., 2024.
2
+
3
+ from .maxcut import MaxCutModel
4
+ from .partition import GraphPartitionModel
5
+
6
+ __all__ = ["MaxCutModel", "GraphPartitionModel"]
@@ -1,20 +1,24 @@
1
1
  # (C) Quantum Computing Inc., 2024.
2
+ from typing import Tuple
2
3
  import numpy as np
3
4
  import networkx as nx
4
5
  from .base import NodeModel
6
+ from eqc_models.base.quadratic import ConstrainedQuadraticModel
5
7
 
6
-
7
- class MaxKCutModel(NodeModel):
8
+ class MaxKCutModel(ConstrainedQuadraticModel):
9
+ _objective = None
8
10
 
9
11
  def __init__(self, G : nx.Graph, k : int):
10
- super(MaxKCutModel, self).__init__(G)
12
+ self.G = G
11
13
  self.k = k
12
- self.lhs = None
13
- self.rhs = None
14
- self._objective = None
15
- self._J = None
16
- self._C = None
17
-
14
+ A, b = self._build_constraints()
15
+ c, J = self.costFunction()
16
+ ConstrainedQuadraticModel.__init__(self, c, J, A, b)
17
+ if k < 3:
18
+ raise ValueError("k must be greater than 2")
19
+ n = len(G.nodes) * k
20
+ self.upper_bound = np.ones((n,))
21
+
18
22
  def decode(self, solution: np.ndarray) -> np.ndarray:
19
23
  """ Override the default decoding to use a the max cut metric to determine a solution """
20
24
 
@@ -22,7 +26,8 @@ class MaxKCutModel(NodeModel):
22
26
  # rather than the same cutoff per node, use the max value per partition
23
27
  decoded_solution = np.zeros_like(solution, dtype=np.int32)
24
28
  k = self.k
25
- for i, u in enumerate(self.variables):
29
+ G = self.G
30
+ for i, u in enumerate(G.nodes):
26
31
  idx = slice(k*i, k*(i+1))
27
32
  spins = solution[idx]
28
33
  mx = np.max(spins)
@@ -35,9 +40,9 @@ class MaxKCutModel(NodeModel):
35
40
  def partition(self, solution):
36
41
  """ Return a dictionary with the partition number of each node """
37
42
  k = self.k
38
- n = len(self.variables)
43
+ G = self.G
39
44
  partition_num = {}
40
- for i, u in enumerate(self.variables):
45
+ for i, u in enumerate(G.nodes):
41
46
  for j in range(k):
42
47
  if solution[i*k+j] == 1:
43
48
  partition_num[u] = j+1
@@ -50,10 +55,10 @@ class MaxKCutModel(NodeModel):
50
55
  cut_size += 1
51
56
  return cut_size
52
57
 
53
- def _build_objective(self):
58
+ def costFunction(self) -> Tuple:
54
59
 
55
- node_map = self.variables
56
60
  G = self.G
61
+ node_map = list(G.nodes)
57
62
  m = len(G.nodes)
58
63
  n = self.k * m
59
64
  # construct the quadratic portion of the objective
@@ -70,12 +75,12 @@ class MaxKCutModel(NodeModel):
70
75
  idx1 = ibase + incr1
71
76
  idx2 = jbase + incr2
72
77
  objective[idx1, idx2] += -1
73
- self._objective = (np.zeros((n, 1)), objective)
78
+ return (np.zeros((n, 1)), objective)
74
79
 
75
80
  def _build_constraints(self):
76
81
 
77
- node_map = self.variables
78
82
  G = self.G
83
+ node_map = list(G.nodes)
79
84
  m = len(G.nodes)
80
85
  n = self.k * m
81
86
 
@@ -86,78 +91,31 @@ class MaxKCutModel(NodeModel):
86
91
  i = node_map.index(u)
87
92
  ibase = i * self.k
88
93
  A[i, ibase:ibase+self.k] = 1
89
- self.lhs = A
90
- self.rhs = b
91
-
92
- def build(self, multiplier=None):
93
- """ Create the constraints and objective and Hamiltonian """
94
-
95
- # there are k * m variables in this problem where m is the number of nodes in the graph
96
- node_map = self.variables
97
- G = self.G
98
- m = len(G.nodes)
99
- n = self.k * m
100
- self.upper_bound = np.ones((n,))
101
-
102
- self._build_objective()
103
- if multiplier is None:
104
- multiplier = np.max(np.abs(self._objective[1]))
105
- self._build_constraints()
106
-
107
- self._C, self._J = self.buildH(multiplier)
108
- self.sum_constraint = m
109
-
110
- def buildH(self, multiplier):
111
- """ Combine the objective and penalties using the multiplier """
112
-
113
- objC, objJ = self.objective
114
- lhs, rhs = self.constraints
115
- Pq = lhs.T@lhs
116
- Pl = -2 * rhs.T@lhs
117
- offset = rhs.T@rhs
118
- n = self.n
119
- J = np.zeros((n, n), np.float32)
120
- C = np.zeros([n, 1], np.float32)
121
- C += objC
122
- J[:,:] += objJ
123
- C += multiplier * Pl.reshape((n, 1))
124
- J[:,:] += multiplier * Pq
125
- return C, J
94
+ return A, b
126
95
 
127
96
  @property
128
97
  def constraints(self):
129
98
  """ Return LHS, RHS in numpy matrix format """
130
- if self.rhs is None:
131
- self.build()
99
+
132
100
  return self.lhs, self.rhs
133
101
 
134
102
  @property
135
103
  def objective(self):
136
104
  """ Return the quadratic objective as NxN+1 matrix """
137
105
 
138
- if self._objective is None:
139
- self.build()
140
106
  return self._objective
141
107
 
142
- @property
143
- def H(self):
144
- """ Return the Hamiltonian as parts C, J """
145
-
146
- if self._C is None:
147
- self.build()
148
- return self._C, self._J
149
-
150
108
  class WeightedMaxKCutModel(MaxKCutModel):
151
109
 
152
110
  def __init__(self, G: nx.Graph, k: int, weight_label : str = "weight"):
153
- super().__init__(G, k)
111
+ super(WeightedMaxCutModel).__init__(G, k)
154
112
 
155
113
  self.weight_label = weight_label
156
114
 
157
115
  def _build_objective(self):
158
116
 
159
- node_map = self.variables
160
117
  G = self.G
118
+ node_map = list(G.nodes)
161
119
  m = len(G.nodes)
162
120
  n = self.k * m
163
121
  # construct the quadratic portion of the objective
@@ -174,7 +132,7 @@ class WeightedMaxKCutModel(MaxKCutModel):
174
132
  idx1 = ibase + incr1
175
133
  idx2 = jbase + incr2
176
134
  objective[idx1, idx2] += G[u][v][self.weight_label]
177
- self._objective = (np.zeros((n, 1)), objective)
135
+ return (np.zeros((n, 1)), objective)
178
136
 
179
137
  def getCutSize(self, partition):
180
138
  cut_size = 0
@@ -68,10 +68,19 @@ class QciClientMixin:
68
68
  client = QciClient(url=self.url, api_token=self.api_token)
69
69
  return client
70
70
 
71
+ def getMetrics(self, job_id : str) -> Dict:
72
+ """
73
+ Returns a dictionary containing the job metrics.
74
+
75
+ """
76
+ client = self.client
77
+ metrics = client.get_job_metrics(job_id=job_id)
78
+ return metrics
79
+
71
80
  class Dirac1Mixin:
72
81
  sampler_type = "dirac-1"
73
82
  requires_operator = "qubo"
74
- max_upper_bound = 1
83
+ max_upper_bound = 205 # log encoding beyond this level has inherent issues
75
84
  job_params_names = ["num_samples", "alpha", "atol"]
76
85
 
77
86
  class QuboSolverMixin:
@@ -141,7 +150,7 @@ class Dirac3Mixin:
141
150
  poly_indices = polynomial.indices
142
151
  data = []
143
152
  # must find these attributes of the polynomial before uploading
144
- max_degree = 0
153
+ max_degree = 2
145
154
  min_degree = len(poly_indices[-1])
146
155
  num_variables = 0
147
156
  for i in range(len(poly_coeffs)):
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: eqc-models
3
- Version: 0.10.0
3
+ Version: 0.10.3
4
4
  Summary: Optimization and ML modeling package targeting EQC devices
5
5
  Author: Quantum Computing Inc.
6
6
  Author-email: support@quantumcomputinginc.com
@@ -22,6 +22,7 @@ Provides-Extra: dev
22
22
  Requires-Dist: pytest<8,>=7.1.0; extra == "dev"
23
23
  Requires-Dist: pytest-cov; extra == "dev"
24
24
  Requires-Dist: sphinx_rtd_theme<2,>=1.3.0; extra == "dev"
25
+ Dynamic: license-file
25
26
 
26
27
  # EQC Models
27
28
 
@@ -0,0 +1,59 @@
1
+ eqc_models-0.10.3.data/platlib/compile_extensions.py,sha256=ivFZ87WFzBITU7IwK_72C41MDNMortJIF8tKevm2aW4,1946
2
+ eqc_models-0.10.3.data/platlib/eqc_models/__init__.py,sha256=WPUijJz2-4UZU-ZTqBofDc-Yaah24geHdmF16SkwIj4,683
3
+ eqc_models-0.10.3.data/platlib/eqc_models/decoding.py,sha256=G3JgbIFzvZ3DIKW0kZ1JeTMIZmrc8hy9kzdbX2Xv5Og,637
4
+ eqc_models-0.10.3.data/platlib/eqc_models/algorithms/__init__.py,sha256=lzQoMMSs2QTqp5suEYNvcQaSEN16d0LwIsZ1mRstumU,135
5
+ eqc_models-0.10.3.data/platlib/eqc_models/algorithms/base.py,sha256=qfQQTwuVyewn7Qpg1_SVoD_7TsdA8vdwSKGqOeZSmNI,204
6
+ eqc_models-0.10.3.data/platlib/eqc_models/algorithms/penaltymultiplier.py,sha256=SndGxCZDS3JTaxFOPJpTBumFdIKcB0dKwSHwfl_BI6o,7845
7
+ eqc_models-0.10.3.data/platlib/eqc_models/allocation/__init__.py,sha256=op_udrapTlWrakTuQId3M0ggo-Y1w4nGJLPcYKOQ-8I,239
8
+ eqc_models-0.10.3.data/platlib/eqc_models/allocation/allocation.py,sha256=PAQn4M75Zegeoy0i6r3hycWs4TKeRglHk05TvwZOoLk,15506
9
+ eqc_models-0.10.3.data/platlib/eqc_models/allocation/portbase.py,sha256=BTnYYduHydPbrE2yQr_Sgv3XJACH_GpIJstuMrfGqCU,3269
10
+ eqc_models-0.10.3.data/platlib/eqc_models/allocation/portmomentum.py,sha256=oMod63rNDC-01dLZjmhUb24SN3_GVgfc6CItgQL_obI,3756
11
+ eqc_models-0.10.3.data/platlib/eqc_models/assignment/__init__.py,sha256=CX_QYl8P1meajV8gcVs6hm07VhoLVe8uu436t7-1XQo,86
12
+ eqc_models-0.10.3.data/platlib/eqc_models/assignment/qap.py,sha256=WMiQQmTORsgi2w7kbmMA1xo-93dESLECWqYTF-zkmTs,2963
13
+ eqc_models-0.10.3.data/platlib/eqc_models/assignment/setpartition.py,sha256=5SQxF_ZlQk4ubWf5_3TgL83k01hAakUP-5AydlD-BvE,161
14
+ eqc_models-0.10.3.data/platlib/eqc_models/base/__init__.py,sha256=RwZguuucmsuOSVqfPLBqj-wzinBOzcgO-2ifFU-DCqg,2885
15
+ eqc_models-0.10.3.data/platlib/eqc_models/base/base.py,sha256=tL6z0MW4ffMKWlozZ0CH4soTiKxSlMXqyVDctaA110U,6405
16
+ eqc_models-0.10.3.data/platlib/eqc_models/base/constraints.py,sha256=KMPyCdt_8GMWLnVEdpzw1T1WqXm2f7Lh629ClUH7XDY,8271
17
+ eqc_models-0.10.3.data/platlib/eqc_models/base/operators.py,sha256=9nCeN6fRP-_YBfs-Gm57D-O_376qcOQiqGDuVlSlf00,7392
18
+ eqc_models-0.10.3.data/platlib/eqc_models/base/polyeval.c,sha256=OHAMclzGp8GW6JPF2cANT8tTA4Wj0n82nucfJquMkO8,438431
19
+ eqc_models-0.10.3.data/platlib/eqc_models/base/polyeval.cpython-310-darwin.so,sha256=EqawhkeRtBexOXXkt-k12SIN76LAlVCIW9taTWFn0GA,101136
20
+ eqc_models-0.10.3.data/platlib/eqc_models/base/polyeval.pyx,sha256=76Bf99Jt1_rLh5byrZxAjavE2F4_yCysirViqOBFIXw,2547
21
+ eqc_models-0.10.3.data/platlib/eqc_models/base/polynomial.py,sha256=FQA26ihFlwfHz9k9XP3qDM0hl5Ko4rtUxiXloj3ail4,13056
22
+ eqc_models-0.10.3.data/platlib/eqc_models/base/quadratic.py,sha256=BHZKniUvSq30pZgzguVasdO39BCEYue_wi5AIklPGS8,8062
23
+ eqc_models-0.10.3.data/platlib/eqc_models/combinatorics/__init__.py,sha256=BhzcVxwpWu2b4jIe0bmPzD5VmSyzwp0oW2q9iYx2IUs,167
24
+ eqc_models-0.10.3.data/platlib/eqc_models/combinatorics/setcover.py,sha256=T5hXoE9Ecw3mTHPLmifBwTzpF_4MhoCUgo2rkSOWt5s,3396
25
+ eqc_models-0.10.3.data/platlib/eqc_models/combinatorics/setpartition.py,sha256=ZD69kgEYSU3KWnx0b4MVCP8XSxbA_VCXOW22_Yssl_M,6254
26
+ eqc_models-0.10.3.data/platlib/eqc_models/graph/__init__.py,sha256=zlPE_c92wsuzz_wQLs0nxYi7tHCYxrPs-yOa9BhQAIo,162
27
+ eqc_models-0.10.3.data/platlib/eqc_models/graph/base.py,sha256=j48OwhorZ5jTlTysTmMiXCeiAdj6jylBREk3NxCpFLI,2072
28
+ eqc_models-0.10.3.data/platlib/eqc_models/graph/hypergraph.py,sha256=ABvutT0NOdIEpUF4TjUzboE4Y_J5iUZyj6-AzKr4R28,13268
29
+ eqc_models-0.10.3.data/platlib/eqc_models/graph/maxcut.py,sha256=o8xVsAwTa9jcpmsIoCQ5z7HSstVdraT8TENomdT519o,4132
30
+ eqc_models-0.10.3.data/platlib/eqc_models/graph/maxkcut.py,sha256=rEDBjto2MbuPh4c0RwTOZoVffKgcriqHNOZAIuBlclQ,4654
31
+ eqc_models-0.10.3.data/platlib/eqc_models/graph/partition.py,sha256=HMpRRipLp14x8pHucY-g6fU7v0PGoy1pf_KpzbanfD0,5800
32
+ eqc_models-0.10.3.data/platlib/eqc_models/ml/__init__.py,sha256=CLfraacr0FrD5ynxlNB6cyNy0lpbavcQT45TvkDrNvY,369
33
+ eqc_models-0.10.3.data/platlib/eqc_models/ml/classifierbase.py,sha256=1yXufiUGpaiBjI2evMiwfYn-Zr-SnWwCnvtREqprtJw,2184
34
+ eqc_models-0.10.3.data/platlib/eqc_models/ml/classifierqboost.py,sha256=5Dcpd0DjpMmlUULyZFKKWm4UuZpeMaknWKViiIjwc0U,18978
35
+ eqc_models-0.10.3.data/platlib/eqc_models/ml/classifierqsvm.py,sha256=b6TdwlghR84UoQpfUThwMwNF_wmkABbCqOn6T1uY2dA,6636
36
+ eqc_models-0.10.3.data/platlib/eqc_models/ml/clustering.py,sha256=yhh6jlgwZiQVn9h2pnYBlzVTCocK7rzsEurSQxCn5FQ,9486
37
+ eqc_models-0.10.3.data/platlib/eqc_models/ml/clusteringbase.py,sha256=AvQbt6jeocBAGCuAmXHKyr3wLWqYUtBDq9PbsEOSlSc,2632
38
+ eqc_models-0.10.3.data/platlib/eqc_models/ml/cvqboost_hamiltonian.pyx,sha256=3PMmEJ_xfmmWXGfire0t-WASnmKj6-CblufgQ2NTARo,2111
39
+ eqc_models-0.10.3.data/platlib/eqc_models/ml/cvqboost_hamiltonian_c_func.c,sha256=ZoKgm_uGjTewhk4W6s-x8QoFuZO0KVkxILIFh6JKsoI,1851
40
+ eqc_models-0.10.3.data/platlib/eqc_models/ml/cvqboost_hamiltonian_c_func.h,sha256=aOImMG5pziUnZxGpDXyWjLrvcY7ZdsczwwSQ2ay4T88,272
41
+ eqc_models-0.10.3.data/platlib/eqc_models/ml/decomposition.py,sha256=Nsnq0GmINpbGOszndgCHXqKdECNpiNiampBrHPU_Gjg,8943
42
+ eqc_models-0.10.3.data/platlib/eqc_models/ml/forecast.py,sha256=fFcBxQK9ZryfEuyvlr9HXicHoZRzLFybimYYttzhI9E,7403
43
+ eqc_models-0.10.3.data/platlib/eqc_models/ml/forecastbase.py,sha256=s-6nUMvtYqG07r7MmmkFVj8_QqgeGkD-HVoEEDTE2bk,3654
44
+ eqc_models-0.10.3.data/platlib/eqc_models/ml/regressor.py,sha256=LA1woXCnefG0wfoOxilX1kszgCUmfNcbQgs_WZ4Ai0o,5683
45
+ eqc_models-0.10.3.data/platlib/eqc_models/ml/regressorbase.py,sha256=H5E8-8pUji1oH5JRdS37LJQoHuKt2JU8eXCZp-ZaEM4,2109
46
+ eqc_models-0.10.3.data/platlib/eqc_models/ml/reservoir.py,sha256=cPRvpCaWLYTBkui35jCssHcOPQgSQZallrG6Ac9djVI,2827
47
+ eqc_models-0.10.3.data/platlib/eqc_models/sequence/__init__.py,sha256=VXlYufO3GYFsM00oii9Cite2WsQEF8XTwRcjLPH_Zlg,92
48
+ eqc_models-0.10.3.data/platlib/eqc_models/sequence/tsp.py,sha256=YM641FTyK5NkgRGxHrU1QmMkEU0gf77nEmIElTqa6Qw,7680
49
+ eqc_models-0.10.3.data/platlib/eqc_models/solvers/__init__.py,sha256=hTjJI4F0FNDgQlK_oRHJxLIkg6of3I1-nEqU_3RL4Gk,542
50
+ eqc_models-0.10.3.data/platlib/eqc_models/solvers/qciclient.py,sha256=uZrtK03oA9ozTGD--hUicmu8zoHYkuIaJ924tOtGwzU,27269
51
+ eqc_models-0.10.3.data/platlib/eqc_models/utilities/__init__.py,sha256=SI2U7JKmPWSiq-F1WcSyfd7l9V6nbOZv_p8quMAZaT0,340
52
+ eqc_models-0.10.3.data/platlib/eqc_models/utilities/fileio.py,sha256=alWPTfjGFx6Iio9HZAAWtYcLmZsBBifg6S6_YbFMQhk,1088
53
+ eqc_models-0.10.3.data/platlib/eqc_models/utilities/polynomial.py,sha256=blXfu7Ehz9lT4nEmIinRzJOL27_qUHSbQ57zxmwDJCA,4735
54
+ eqc_models-0.10.3.data/platlib/eqc_models/utilities/qplib.py,sha256=Do-MjmCFdI5HyDOAjfoz4_5lugySLMBlMAWDLUWx2OA,15796
55
+ eqc_models-0.10.3.dist-info/licenses/LICENSE.txt,sha256=8eh0oqsNNVR1Jk-13gkqRRSo2axtUU5kp2KzH4f9u3U,11354
56
+ eqc_models-0.10.3.dist-info/METADATA,sha256=FnNDJZMf48W-Xe09DRn9T4iEJjHoXJleIui-4Dy23nU,7129
57
+ eqc_models-0.10.3.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
58
+ eqc_models-0.10.3.dist-info/top_level.txt,sha256=9ZfFeKNEvkRlKWoUnfcZ9TzmTdgdsuPEnTPy11Hqf4Q,30
59
+ eqc_models-0.10.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,115 +0,0 @@
1
- import os
2
- import logging
3
- from typing import (Dict, List, Tuple)
4
- import numpy as np
5
- from eqc_direct.client import EqcClient
6
-
7
- log = logging.getLogger(name=__name__)
8
-
9
- # base class
10
- class EqcModel:
11
- """ EqcModel subclasses must provide these properties/methods.
12
-
13
- :decode: takes a raw solution and translates it into the original problem
14
- formulation
15
- :H: property which returns a Hamiltonian operator
16
- :levels: property to set the number of levels in each qudit
17
- :qudit_limits: maximjm value permitted for each qudit """
18
-
19
- _levels = 100
20
- _domains = None
21
- _H = None
22
- _machine_slacks = 0
23
-
24
- def decode(self, solution : np.ndarray) -> np.ndarray:
25
- """ Interpret the solution given the norm value and domains """
26
-
27
- # ignore any slacks that may have been added during encoding
28
- solution = solution[:self.n]
29
- if self._domains is not None:
30
- multipliers = self.domains / self.sum_constraint
31
- else:
32
- multipliers = self.sum_constraint / np.sum(solution)
33
-
34
- return multipliers * solution
35
-
36
- def encode(self, norm_value:float=1000) -> np.ndarray:
37
- """ Encode Hamiltonian into the domain of the device """
38
-
39
- raise NotImplementedError()
40
-
41
- def encode_sum_constraint(self, levels):
42
- new_sc = self.n * (levels-1) * self.sum_constraint / (np.sum(self.domains))
43
- return new_sc
44
-
45
- @property
46
- def domains(self) -> np.array:
47
- return self._domains
48
-
49
- @domains.setter
50
- def domains(self, value):
51
- self._domains = value
52
-
53
- @property
54
- def n(self) -> int:
55
- return int(max(self.domains.shape))
56
-
57
- def processH(self, H : np.ndarray) -> np.ndarray:
58
- """ By default, do nothing to H """
59
-
60
- return H
61
-
62
- @property
63
- def H(self) -> Dict[str, np.ndarray]:
64
- """ Matrix of a quadratic operator with the first column containing
65
- the linear terms and the remaining columns containing a symmetric
66
- quadratic matrix"""
67
- return self._H
68
-
69
- @H.setter
70
- def H(self, value : Dict[str, np.ndarray]):
71
- """ The H setter ensures that matrices order 2 and above are symmetric """
72
-
73
- H = self.processH(value)
74
- self._H = H
75
-
76
- @property
77
- def sparse(self) -> Tuple[np.ndarray, np.ndarray]:
78
- H = self.H
79
- coeff = []
80
- idx = []
81
- poly_orders = {"C": 1, "J": 2, "T": 3, "Q": 4, "P": 5}
82
- key_len = max([poly_orders[k] for k, v in H.items() if v is not None])
83
-
84
-
85
- @property
86
- def machine_slacks(self):
87
- """ Number of slack qudits to add to the model """
88
- return self._machine_slacks
89
-
90
- @machine_slacks.setter
91
- def machine_slacks(self, value:int):
92
- assert int(value) == value, "value not integer"
93
- self._machine_slacks = value
94
-
95
- class ModelSolver:
96
- """ Provide a common interface for solver implementations.
97
- Store a model, implement a solve method."""
98
-
99
- def __init__(self, model : EqcModel, levels : int = 200):
100
- self.model = model
101
- self._levels = levels
102
-
103
- def solve(self, *args, **kwargs) -> Dict:
104
- raise NotImplementedError()
105
-
106
- @property
107
- def levels(self) -> int:
108
- """ This integer value indicates the number of distinct
109
- states each qudit can represent. These levels are separated
110
- by some constant value with the first level taking the value 0. """
111
- return self._levels
112
-
113
- @levels.setter
114
- def levels(self, value : int):
115
- self._levels = value
@@ -1,25 +0,0 @@
1
- # (C) Quantum Computing Inc., 2024.
2
- import numpy as np
3
- import networkx as nx
4
- from .graphs import GraphModel
5
-
6
- class CommunityDetectionModel(GraphModel):
7
- """
8
- This model is the generic n-community model, which requires enforcing
9
- membership to a single community
10
-
11
- """
12
-
13
- def __init__(self, G : nx.Graph, num_communities : int):
14
- super(CommunityDetectionModel, self).__init__(G)
15
- self.cnum_communities = num_communities
16
-
17
- def build(self):
18
- # num_nodes = len(self.G.nodes)
19
- # num_variables = num_nodes * self.num_communities
20
- # lhs = np.zeros((num_nodes, num_variables), dtype=np.int32)
21
- # rhs = np.ones((num_nodes, 1), dtype=np.int32)
22
- # for i in range(num_nodes):
23
- # lhs[i, 3*i:3*(i+1)] = 1
24
- # self.constraints = lhs, rhs
25
- raise NotImplementedError("Community Detection is not implemented yet")
@@ -1,61 +0,0 @@
1
- from typing import Dict
2
- import logging
3
- import numpy as np
4
- from eqc_direct.client import EqcClient
5
- from .base import ModelSolver
6
-
7
- log = logging.getLogger(name=__name__)
8
-
9
- class EqcDirectMixin:
10
-
11
- ip_addr = None
12
- port = None
13
-
14
- def connect(self, ip_addr : str, port : str):
15
- """ Explicitly set device address, if environment is configured with the connection, this call is not required """
16
- self.ip_addr = ip_addr
17
- self.port = port
18
-
19
- @property
20
- def client(self):
21
-
22
- params = {}
23
- if self.ip_addr is not None:
24
- params["ip_address"] = self.ip_addr
25
- if self.port is not None:
26
- params["port"] = self.port
27
- return EqcClient(**params)
28
-
29
- class EqcDirectSolver(ModelSolver, EqcDirectMixin):
30
-
31
- def solve(self, relaxation_schedule:int=2, precision : float = 1.0) -> Dict:
32
- model = self.model
33
- poly_coefficients, poly_indices = model.sparse
34
- scval = model.encode_sum_constraint(self.levels)
35
-
36
- client = self.client
37
- lock_id, start_ts, end_ts = client.wait_for_lock()
38
- log.debug("Got device lock id %s. Wait time %f", lock_id, end_ts - start_ts)
39
- resp = None
40
- try:
41
- log.debug("Calling device with parameters relaxation_schedule %d sum_constraint %s lock_id %s solution_precision %f",
42
- relaxation_schedule, scval, lock_id, precision)
43
- resp = client.process_job(poly_coefficients=poly_coefficients,
44
- poly_indices=poly_indices,
45
- relaxation_schedule=relaxation_schedule,
46
- sum_constraint = scval,
47
- lock_id = lock_id,
48
- solution_precision=precision)
49
- log.debug("Received response with status %s", resp["err_desc"])
50
- log.debug("Runtime %f resulting in energy %f", resp["runtime"], resp["energy"])
51
- log.debug("Distillation runtime %s resulting in energy %f", resp["distilled_runtime"], resp["distilled_energy"])
52
- finally:
53
- client.release_lock(lock_id=lock_id)
54
- if resp is not None:
55
- solution = resp["solution"]
56
- energy = resp["energy"]
57
- runtime = resp["runtime"]
58
- dirac3_sol = np.array(solution)
59
- else:
60
- raise RuntimeError("FAILED TO GET RESPONSE")
61
- return resp
@@ -1,5 +0,0 @@
1
- # (C) Quantum Computing Inc., 2024.
2
-
3
- from .maxcut import MaxCutModel
4
-
5
- __all__ = ["MaxCutModel"]