Skip to content

Commit a205d89

Browse files
committed
Fix circular imports
1 parent 48f10ab commit a205d89

File tree

6 files changed

+145
-142
lines changed

6 files changed

+145
-142
lines changed

dwave/plugins/networkx/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
from dwave.plugins.networkx.algorithms import *
2020

2121
import dwave.plugins.networkx.utils
22+
23+
import dwave.plugins.networkx.exceptions
2224
from dwave.plugins.networkx.exceptions import *
2325

2426
import dwave.plugins.networkx.default_sampler

dwave/plugins/networkx/algorithms/clique.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@
1313
# limitations under the License.
1414

1515
import networkx as nx
16-
import dwave.plugins.networkx as dnx
1716

17+
from dwave.plugins.networkx.algorithms.independent_set import maximum_independent_set
1818
from dwave.plugins.networkx.utils import binary_quadratic_model_sampler
1919

20+
2021
__all__ = ["maximum_clique", "clique_number", "is_clique"]
2122

23+
2224
@binary_quadratic_model_sampler(1)
2325
def maximum_clique(G, sampler=None, lagrange=2.0, **sampler_args):
2426
"""
@@ -87,7 +89,7 @@ def maximum_clique(G, sampler=None, lagrange=2.0, **sampler_args):
8789
# finding the maximum clique in a graph is equivalent to finding
8890
# the independent set in the complementary graph
8991
complement_G = nx.complement(G)
90-
return dnx.maximum_independent_set(complement_G, sampler, lagrange, **sampler_args)
92+
return maximum_independent_set(complement_G, sampler, lagrange, **sampler_args)
9193

9294

9395
@binary_quadratic_model_sampler(1)
@@ -145,6 +147,7 @@ def clique_number(G, sampler=None, lagrange=2.0, **sampler_args):
145147
"""
146148
return len(maximum_clique(G, sampler, lagrange, **sampler_args))
147149

150+
148151
def is_clique(G, clique_nodes):
149152
"""Determines whether the given nodes form a clique.
150153

dwave/plugins/networkx/default_sampler.py

+131-3
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,143 @@
6161
[0]
6262
6363
"""
64+
from decorator import decorator
6465

65-
from dwave.plugins.networkx.utils.decorators import binary_quadratic_model_sampler
66-
67-
__all__ = ['set_default_sampler', 'get_default_sampler', 'unset_default_sampler']
66+
__all__ = ['set_default_sampler',
67+
'get_default_sampler',
68+
'unset_default_sampler',
69+
]
6870

6971

7072
_SAMPLER = None
7173

7274

75+
def binary_quadratic_model_sampler(which_args):
76+
"""Decorator to validate sampler arguments.
77+
78+
Parameters
79+
----------
80+
which_args : int or sequence of ints
81+
Location of the sampler arguments of the input function in the form
82+
`function_name(args, *kw)`. If more than one
83+
sampler is allowed, can be a list of locations.
84+
85+
Returns
86+
-------
87+
_binary_quadratic_model_sampler : function
88+
Caller function that validates the sampler format. A sampler
89+
is expected to have `sample_qubo` and `sample_ising` methods.
90+
Alternatively, if no sampler is provided (or sampler is None),
91+
the sampler set by the `set_default_sampler` function is provided to
92+
the function.
93+
94+
Examples
95+
--------
96+
Decorate functions like this::
97+
98+
@binary_quadratic_model_sampler(1)
99+
def maximal_matching(G, sampler, **sampler_args):
100+
pass
101+
102+
This example validates two placeholder samplers, which return a correct
103+
response only in the case of finding an independent set on a complete graph
104+
(where one node is always an independent set), the first valid, the second
105+
missing a method.
106+
107+
>>> import networkx as nx
108+
>>> import dwave.plugins.networkx as dnx
109+
>>> from dwave.plugins.networkx.utils import decorators
110+
>>> # Create two placeholder samplers
111+
>>> class WellDefinedSampler:
112+
... # an example sampler, only works for independent set on complete
113+
... # graphs
114+
... def __init__(self, name):
115+
... self.name = name
116+
... def sample_ising(self, h, J):
117+
... sample = {v: -1 for v in h}
118+
... sample[0] = 1 # set one node to true
119+
... return [sample]
120+
... def sample_qubo(self, Q):
121+
... sample = {v: 0 for v in set().union(*Q)}
122+
... sample[0] = 1 # set one node to true
123+
... return [sample]
124+
... def __str__(self):
125+
... return self.name
126+
...
127+
>>> class IllDefinedSampler:
128+
... # an example sampler missing a `sample_qubo` method
129+
... def __init__(self, name):
130+
... self.name = name
131+
... def sample_ising(self, h, J):
132+
... sample = {v: -1 for v in h}
133+
... sample[0] = 1 # set one node to true
134+
... return [sample]
135+
... def __str__(self):
136+
... return self.name
137+
...
138+
>>> sampler1 = WellDefinedSampler('sampler1')
139+
>>> sampler2 = IllDefinedSampler('sampler2')
140+
>>> # Define a placeholder independent-set function with the decorator
141+
>>> @dnx.utils.binary_quadratic_model_sampler(1)
142+
... def independent_set(G, sampler, **sampler_args):
143+
... Q = {(node, node): -1 for node in G}
144+
... Q.update({edge: 2 for edge in G.edges})
145+
... response = sampler.sample_qubo(Q, **sampler_args)
146+
... sample = next(iter(response))
147+
... return [node for node in sample if sample[node] > 0]
148+
...
149+
>>> # Validate the samplers
150+
>>> G = nx.complete_graph(5)
151+
>>> independent_set(G, sampler1)
152+
[0]
153+
>>> independent_set(G, sampler2) # doctest: +SKIP
154+
---------------------------------------------------------------------------
155+
TypeError Traceback (most recent call last)
156+
<ipython-input-35-670b71b268c7> in <module>()
157+
----> 1 independent_set(G, IllDefinedSampler)
158+
<decorator-gen-628> in independent_set(G, sampler, **sampler_args)
159+
/usr/local/lib/python2.7/dist-packages/dwave.plugins.networkx/utils/decorators.pyc in _binary_quadratic_model_sampler(f, *args, **kw)
160+
61
161+
62 if not hasattr(sampler, "sample_qubo") or not callable(sampler.sample_qubo):
162+
---> 63 raise TypeError("expected sampler to have a 'sample_qubo' method")
163+
64 if not hasattr(sampler, "sample_ising") or not callable(sampler.sample_ising):
164+
65 raise TypeError("expected sampler to have a 'sample_ising' method")
165+
TypeError: expected sampler to have a 'sample_qubo' method
166+
167+
"""
168+
@decorator
169+
def _binary_quadratic_model_sampler(f, *args, **kw):
170+
# convert into a sequence if necessary
171+
if isinstance(which_args, int):
172+
iter_args = (which_args,)
173+
else:
174+
iter_args = iter(which_args)
175+
176+
# check each sampler for the correct methods
177+
new_args = [arg for arg in args]
178+
for idx in iter_args:
179+
sampler = args[idx]
180+
181+
# if no sampler is provided, get the default sampler if it has
182+
# been set
183+
if sampler is None:
184+
# this sampler has already been vetted
185+
default_sampler = get_default_sampler()
186+
if default_sampler is None:
187+
raise DWaveNetworkXMissingSampler('no default sampler set')
188+
new_args[idx] = default_sampler
189+
continue
190+
191+
if not hasattr(sampler, "sample_qubo") or not callable(sampler.sample_qubo):
192+
raise TypeError("expected sampler to have a 'sample_qubo' method")
193+
if not hasattr(sampler, "sample_ising") or not callable(sampler.sample_ising):
194+
raise TypeError("expected sampler to have a 'sample_ising' method")
195+
196+
# now run the function and return the results
197+
return f(*new_args, **kw)
198+
return _binary_quadratic_model_sampler
199+
200+
73201
@binary_quadratic_model_sampler(0)
74202
def set_default_sampler(sampler):
75203
"""Sets a default binary quadratic model sampler.

dwave/plugins/networkx/exceptions.py

+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121

2222
from networkx import NetworkXException
2323

24+
__all__ = ['DWaveNetworkXException',
25+
'DWaveNetworkXMissingSampler',
26+
]
27+
2428

2529
class DWaveNetworkXException(NetworkXException):
2630
"""Base class for exceptions in DWaveNetworkX."""

dwave/plugins/networkx/utils/__init__.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,5 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14-
#
15-
# ================================================================================================
14+
1615
from dwave.plugins.networkx.utils.decorators import *

dwave/plugins/networkx/utils/decorators.py

+2-135
Original file line numberDiff line numberDiff line change
@@ -12,139 +12,6 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
"""
16-
Decorators allow for input checking and default parameter setting for
17-
algorithms.
18-
"""
15+
# this submodule is kept for backwards compatibility
1916

20-
from decorator import decorator
21-
22-
import dwave.plugins.networkx as dnx
23-
24-
__all__ = ['binary_quadratic_model_sampler']
25-
26-
27-
def binary_quadratic_model_sampler(which_args):
28-
"""Decorator to validate sampler arguments.
29-
30-
Parameters
31-
----------
32-
which_args : int or sequence of ints
33-
Location of the sampler arguments of the input function in the form
34-
`function_name(args, *kw)`. If more than one
35-
sampler is allowed, can be a list of locations.
36-
37-
Returns
38-
-------
39-
_binary_quadratic_model_sampler : function
40-
Caller function that validates the sampler format. A sampler
41-
is expected to have `sample_qubo` and `sample_ising` methods.
42-
Alternatively, if no sampler is provided (or sampler is None),
43-
the sampler set by the `set_default_sampler` function is provided to
44-
the function.
45-
46-
Examples
47-
--------
48-
Decorate functions like this::
49-
50-
@binary_quadratic_model_sampler(1)
51-
def maximal_matching(G, sampler, **sampler_args):
52-
pass
53-
54-
This example validates two placeholder samplers, which return a correct
55-
response only in the case of finding an independent set on a complete graph
56-
(where one node is always an independent set), the first valid, the second
57-
missing a method.
58-
59-
>>> import networkx as nx
60-
>>> import dwave.plugins.networkx as dnx
61-
>>> from dwave.plugins.networkx.utils import decorators
62-
>>> # Create two placeholder samplers
63-
>>> class WellDefinedSampler:
64-
... # an example sampler, only works for independent set on complete
65-
... # graphs
66-
... def __init__(self, name):
67-
... self.name = name
68-
... def sample_ising(self, h, J):
69-
... sample = {v: -1 for v in h}
70-
... sample[0] = 1 # set one node to true
71-
... return [sample]
72-
... def sample_qubo(self, Q):
73-
... sample = {v: 0 for v in set().union(*Q)}
74-
... sample[0] = 1 # set one node to true
75-
... return [sample]
76-
... def __str__(self):
77-
... return self.name
78-
...
79-
>>> class IllDefinedSampler:
80-
... # an example sampler missing a `sample_qubo` method
81-
... def __init__(self, name):
82-
... self.name = name
83-
... def sample_ising(self, h, J):
84-
... sample = {v: -1 for v in h}
85-
... sample[0] = 1 # set one node to true
86-
... return [sample]
87-
... def __str__(self):
88-
... return self.name
89-
...
90-
>>> sampler1 = WellDefinedSampler('sampler1')
91-
>>> sampler2 = IllDefinedSampler('sampler2')
92-
>>> # Define a placeholder independent-set function with the decorator
93-
>>> @dnx.utils.binary_quadratic_model_sampler(1)
94-
... def independent_set(G, sampler, **sampler_args):
95-
... Q = {(node, node): -1 for node in G}
96-
... Q.update({edge: 2 for edge in G.edges})
97-
... response = sampler.sample_qubo(Q, **sampler_args)
98-
... sample = next(iter(response))
99-
... return [node for node in sample if sample[node] > 0]
100-
...
101-
>>> # Validate the samplers
102-
>>> G = nx.complete_graph(5)
103-
>>> independent_set(G, sampler1)
104-
[0]
105-
>>> independent_set(G, sampler2) # doctest: +SKIP
106-
---------------------------------------------------------------------------
107-
TypeError Traceback (most recent call last)
108-
<ipython-input-35-670b71b268c7> in <module>()
109-
----> 1 independent_set(G, IllDefinedSampler)
110-
<decorator-gen-628> in independent_set(G, sampler, **sampler_args)
111-
/usr/local/lib/python2.7/dist-packages/dwave.plugins.networkx/utils/decorators.pyc in _binary_quadratic_model_sampler(f, *args, **kw)
112-
61
113-
62 if not hasattr(sampler, "sample_qubo") or not callable(sampler.sample_qubo):
114-
---> 63 raise TypeError("expected sampler to have a 'sample_qubo' method")
115-
64 if not hasattr(sampler, "sample_ising") or not callable(sampler.sample_ising):
116-
65 raise TypeError("expected sampler to have a 'sample_ising' method")
117-
TypeError: expected sampler to have a 'sample_qubo' method
118-
119-
"""
120-
@decorator
121-
def _binary_quadratic_model_sampler(f, *args, **kw):
122-
# convert into a sequence if necessary
123-
if isinstance(which_args, int):
124-
iter_args = (which_args,)
125-
else:
126-
iter_args = iter(which_args)
127-
128-
# check each sampler for the correct methods
129-
new_args = [arg for arg in args]
130-
for idx in iter_args:
131-
sampler = args[idx]
132-
133-
# if no sampler is provided, get the default sampler if it has
134-
# been set
135-
if sampler is None:
136-
# this sampler has already been vetted
137-
default_sampler = dnx.get_default_sampler()
138-
if default_sampler is None:
139-
raise dnx.DWaveNetworkXMissingSampler('no default sampler set')
140-
new_args[idx] = default_sampler
141-
continue
142-
143-
if not hasattr(sampler, "sample_qubo") or not callable(sampler.sample_qubo):
144-
raise TypeError("expected sampler to have a 'sample_qubo' method")
145-
if not hasattr(sampler, "sample_ising") or not callable(sampler.sample_ising):
146-
raise TypeError("expected sampler to have a 'sample_ising' method")
147-
148-
# now run the function and return the results
149-
return f(*new_args, **kw)
150-
return _binary_quadratic_model_sampler
17+
from dwave.plugins.networkx.default_sampler import binary_quadratic_model_sampler

0 commit comments

Comments
 (0)