Skip to content

Commit c50f7f0

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

File tree

6 files changed

+152
-143
lines changed

6 files changed

+152
-143
lines changed

dwave/plugins/networkx/__init__.py

+8-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
@@ -27,5 +29,9 @@
2729
import dwave.plugins.networkx.drawing
2830
from dwave.plugins.networkx.drawing import *
2931

30-
from dwave.plugins.networkx.package_info import __version__, __author__, \
31-
__authoremail__, __description__
32+
from dwave.plugins.networkx.package_info import (
33+
__version__,
34+
__author__,
35+
__authoremail__,
36+
__description__,
37+
)

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

+132-2
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,145 @@
6161
[0]
6262
6363
"""
64+
from decorator import decorator
6465

65-
from dwave.plugins.networkx.utils.decorators import binary_quadratic_model_sampler
66+
from dwave.plugins.networkx.exceptions import DWaveNetworkXMissingSampler
6667

67-
__all__ = ['set_default_sampler', 'get_default_sampler', 'unset_default_sampler']
68+
__all__ = ['set_default_sampler',
69+
'get_default_sampler',
70+
'unset_default_sampler',
71+
]
6872

6973

7074
_SAMPLER = None
7175

7276

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