dimod¶
dimod is a shared API for binary quadratic samplers. It provides a binary quadratic model (BQM) class that contains Ising and quadratic unconstrained binary optimization (QUBO) models used by samplers such as the D-Wave system. It also provides utilities for constructing new samplers and composed samplers and for minor-embedding. Its reference examples include several samplers and composed samplers.
Example Usage¶
The QUBO form, \(\text{E}(a_i, b_{i,j}; q_i) = -q_1 -q_2 + 2q_1 q_2\), is related to the Ising form, \(\text{E}(h_i, j_{i,j}; s_i) = \frac{1}{2}(s_1s_2-1)\), via the simple manipulation \(s_i=2q_i-1\).
This example constructs a simple QUBO and converts it to Ising format.
>>> import dimod
>>> bqm = dimod.BinaryQuadraticModel({0: -1, 1: -1}, {(0, 1): 2}, 0.0, dimod.BINARY) # QUBO
>>> bqm_ising = bqm.change_vartype(dimod.SPIN, inplace=False) # Ising
This example uses one of dimod’s test samplers, ExactSampler, a solver that calculates the energies of all possible samples.
>>> import dimod
>>> h = {0: 0.0, 1: 0.0}
>>> J = {(0, 1): -1.0}
>>> bqm = dimod.BinaryQuadraticModel.from_ising(h, J)
>>> response = dimod.ExactSolver().sample(bqm)
>>> for sample, energy in response.data(['sample', 'energy']): print(sample, energy)
{0: -1, 1: -1} -1.0
{0: 1, 1: 1} -1.0
{0: 1, 1: -1} 1.0
{0: -1, 1: 1} 1.0
Documentation¶
Release: | 0.8.18 |
---|---|
Date: | Dec 24, 2019 |
Introduction¶
dimod provides a binary quadratic model (BQM) class that contains Ising and quadratic unconstrained binary optimization (QUBO) models used, as described in Solving Problems on a D-Wave System, by samplers such as the D-Wave system.
It provides useful functionality for working with these models and samplers; for example BQM Generators to build BQMs and Utilities for calculating the energy of a sample or serializing dimod objects.
It includes reference Samplers and Composites for processing binary quadratic programs and refining sampling, and useful for testing your code during development.
It also provides an API for Samplers and Composites for constructing new samplers and composed samplers tailored for your problem.
Additionally, it provides some Higher-Order Composites and functionality such as reducing higher-order polynomials to BQMs.
Example¶
Solving problems with large numbers of variables might necessitate the use of decomposition[1] methods such as branch-and-bound to reduce the number of variables. The following illustrative example reduces an Ising model for a small problem (the K4 complete graph), and converts the reduced-variables model to QUBO formulation.
[1] | Ocean software’s D-Wave Hybrid provides tools for decomposing large problems. |
>>> import dimod
>>> linear = {1: 1, 2: 2, 3: 3, 4: 4}
>>> quadratic = {(1, 2): 12, (1, 3): 13, (1, 4): 14,
... (2, 3): 23, (2, 4): 24,
... (3, 4): 34}
>>> bqm_k4 = dimod.BinaryQuadraticModel(linear, quadratic, 0.5, dimod.SPIN)
>>> bqm_k4.vartype
<Vartype.SPIN: frozenset([1, -1])>
>>> len(bqm_k4.linear)
4
>>> bqm_k4.contract_variables(2, 3)
>>> len(bqm_k4.linear)
3
>>> bqm_no3_qubo = bqm_k4.binary
>>> bqm_no3_qubo.vartype
<Vartype.BINARY: frozenset([0, 1])>
Samplers and Composites¶
Samplers are processes that sample from low-energy states of a problem’s objective function. A binary quadratic model (BQM) sampler samples from low-energy states in models such as those defined by an Ising equation or a QUBO problem and returns an iterable of samples, in order of increasing energy. A dimod sampler provides ‘sample_qubo’ and ‘sample_ising’ methods as well as the generic BQM sampler method.
Composed samplers apply pre- and/or post-processing to binary quadratic programs without changing the underlying sampler implementation by layering composite patterns on the sampler. For example, a composed sampler might add spin transformations when sampling from the D-Wave system.
Structured samplers are restricted to sampling only binary quadratic models defined on a specific graph.
You can create your own samplers with dimod’s Sampler
abstract base class (ABC)
providing complementary methods (e.g., ‘sample_qubo’ if only ‘sample_ising’ is implemented),
consistent responses, etc.
Examples¶
This first example uses a composed sampler on the Boolean NOT Gate
example detailed in the Getting Started documentation.
The ExactSolver
test sampler calculates the
energy of all possible samples; the FixedVariableComposite
composite sets the value and removes specified variables from the BQM before sending it to
the sampler. Fixing variable x, the input to the NOT gate, to 1 results in valid solution
\(z=0\) having lower energy (-1) than solution \(x=z=1\), which is an invalid
state for a NOT gate.
>>> from dimod import FixedVariableComposite, ExactSolver
>>> Q = {('x', 'x'): -1, ('x', 'z'): 2, ('z', 'x'): 0, ('z', 'z'): -1}
>>> composed_sampler = FixedVariableComposite(ExactSolver())
>>> sampleset = composed_sampler.sample_qubo(Q, fixed_variables={'x': 1})
>>> print(sampleset)
x z energy num_oc.
0 1 0 -1.0 1
1 1 1 0.0 1
['BINARY', 2 rows, 2 samples, 2 variables]
The next example creates a dimod sampler by implementing a single method (in this example
the sample_ising()
method).
class LinearIsingSampler(dimod.Sampler):
def sample_ising(self, h, J):
sample = linear_ising(h, J) # Defined elsewhere
energy = dimod.ising_energy(sample, h, J)
return dimod.Response.from_samples([sample], {'energy': [energy]})
@property
def properties(self):
return dict()
@property
def parameters(self):
return dict()
The Sampler
ABC provides the other sample methods “for free”
as mixins.
Terminology¶
- chain
- A collection of nodes or variables in the target graph/model that we want to act as a single node/variable.
- chain strength
- Magnitude of the negative quadratic bias applied between variables to form a chain.
- composed sampler
- Samplers that apply pre- and/or post-processing to binary quadratic programs without changing the underlying sampler implementation by layering composite patterns on the sampler. For example, a composed sampler might add spin transformations when sampling from the D-Wave system.
- graph
- A collection of nodes and edges. A graph can be derived from a model: a node for each variable and an edge for each pair of variables with a non-zero quadratic bias.
- model
- A collection of variables with associated linear and quadratic biases. Sometimes referred to in other tools as a problem.
- sampler
- A process that samples from low energy states of a problem’s objective function. A binary quadratic model (BQM) sampler samples from low energy states in models such as those defined by an Ising equation or a Quadratic Unconstrained Binary Optimization (QUBO) problem and returns an iterable of samples, in order of increasing energy. A dimod sampler provides ‘sample_qubo’ and ‘sample_ising’ methods as well as the generic BQM sampler method.
- source
- In the context of embedding, the model or induced graph that we wish to embed. Sometimes referred to in other tools as the logical graph/model.
- structured sampler
- Samplers that are restricted to sampling only binary quadratic models defined on a specific graph.
- target
- Embedding attempts to create a target model from a target graph. The process of embedding takes a source model, derives the source graph, maps the source graph to the target graph, then derives the target model. Sometimes referred to in other tools as the embedded graph/model.
Reference Documentation¶
Release: 0.8.18 Date: Dec 24, 2019
Binary Quadratic Models¶
Ising, QUBO, and BQMs¶
The binary quadratic model (BQM) class contains Ising and quadratic unconstrained binary optimization (QUBO) models used by samplers such as the D-Wave system.
The Ising model is an objective function of \(N\) variables \(s=[s_1,...,s_N]\) corresponding to physical Ising spins, where \(h_i\) are the biases and \(J_{i,j}\) the couplings (interactions) between spins.
The QUBO model is an objective function of \(N\) binary variables represented as an upper-diagonal matrix \(Q\), where diagonal terms are the linear coefficients and the nonzero off-diagonal terms the quadratic coefficients.
The BinaryQuadraticModel
class can contain both these models and its methods provide
convenient utilities for working with, and interworking between, the two representations
of a problem.
These models and their use in solving problems on the D-Wave system is described in the following documentation:
- Getting Started with the D-Wave System
- Introduces key concepts such as objective functions, Ising model, QUBOs, and graphs, explains how these models are used to represent problems, and provides some simple examples.
- D-Wave Problem-Solving Handbook
- Provides a variety of techniques for, and examples of, reformulating problems as BQMs.
- Solving Problems on a D-Wave System
- Describes and demonstrates the use of BQM in the context of Ocean software.
Class¶
-
class
BinaryQuadraticModel
(**kwargs)[source]¶ Encodes a binary quadratic model.
Binary quadratic model is the superclass that contains the Ising model and the QUBO.
Parameters: - linear (dict[variable, bias]) – Linear biases as a dict, where keys are the variables of the binary quadratic model and values the linear biases associated with these variables. A variable can be any python object that is valid as a dictionary key. Biases are generally numbers but this is not explicitly checked.
- quadratic (dict[(variable, variable), bias]) – Quadratic biases as a dict, where keys are 2-tuples of variables and values the quadratic biases associated with the pair of variables (the interaction). A variable can be any python object that is valid as a dictionary key. Biases are generally numbers but this is not explicitly checked. Interactions that are not unique are added.
- offset (number) – Constant energy offset associated with the binary quadratic model.
Any input type is allowed, but many applications assume that offset is a number.
See
BinaryQuadraticModel.energy()
. - vartype (
Vartype
/str/set) –Variable type for the binary quadratic model. Accepted input values:
Vartype.SPIN
,'SPIN'
,{-1, 1}
Vartype.BINARY
,'BINARY'
,{0, 1}
- **kwargs – Any additional keyword parameters and their values are stored in
BinaryQuadraticModel.info
.
Notes
The
BinaryQuadraticModel
class does not enforce types on biases and offsets, but most applications that use this class assume that they are numeric.Examples
This example creates a binary quadratic model with three spin variables.
>>> bqm = dimod.BinaryQuadraticModel({0: 1, 1: -1, 2: .5}, ... {(0, 1): .5, (1, 2): 1.5}, ... 1.4, ... dimod.Vartype.SPIN)
This example creates a binary quadratic model with non-numeric variables (variables can be any hashable object).
>>> bqm = dimod.BQM({'a': 0.0, 'b': -1.0, 'c': 0.5}, ... {('a', 'b'): -1.0, ('b', 'c'): 1.5}, ... 1.4, ... dimod.SPIN) >>> len(bqm) 3 >>> 'b' in bqm True
-
linear
¶ Linear biases as a dict, where keys are the variables of the binary quadratic model and values the linear biases associated with these variables.
Type: dict[variable, bias]
-
quadratic
¶ Quadratic biases as a dict, where keys are 2-tuples of variables, which represent an interaction between the two variables, and values are the quadratic biases associated with the interactions.
Type: dict[(variable, variable), bias]
-
offset
¶ The energy offset associated with the model. Same type as given on instantiation.
Type: number
-
variables
¶ The variables in the binary quadratic model as a dictionary keys view object.
Type: keysview
-
adj
¶ The model’s interactions as nested dicts. In graphic representation, where variables are nodes and interactions are edges or adjacencies, keys of the outer dict (adj) are all the model’s nodes (e.g. v) and values are the inner dicts. For the inner dict associated with outer-key/node ‘v’, keys are all the nodes adjacent to v (e.g. u) and values are quadratic biases associated with the pair of inner and outer keys (u, v).
Type: dict
Examples
This example creates an instance of the
BinaryQuadraticModel
class for the K4 complete graph, where the nodes have biases set equal to their sequential labels and interactions are the concatenations of the node pairs (e.g., 23 for u,v = 2,3).>>> import dimod ... >>> linear = {1: 1, 2: 2, 3: 3, 4: 4} >>> quadratic = {(1, 2): 12, (1, 3): 13, (1, 4): 14, ... (2, 3): 23, (2, 4): 24, ... (3, 4): 34} >>> offset = 0.0 >>> vartype = dimod.BINARY >>> bqm_k4 = dimod.BinaryQuadraticModel(linear, quadratic, offset, vartype) >>> bqm_k4.info = {'Complete K4 binary quadratic model.'} >>> bqm_k4.info.issubset({'Complete K3 binary quadratic model.', ... 'Complete K4 binary quadratic model.', ... 'Complete K5 binary quadratic model.'}) True >>> bqm_k4.adj.viewitems() # Show all adjacencies # doctest: +SKIP [(1, {2: 12, 3: 13, 4: 14}), (2, {1: 12, 3: 23, 4: 24}), (3, {1: 13, 2: 23, 4: 34}), (4, {1: 14, 2: 24, 3: 34})] >>> bqm_k4.adj[2] # Show adjacencies for node 2 # doctest: +SKIP {1: 12, 3: 23, 4: 24} >>> bqm_k4.adj[2][3] # Show the quadratic bias for nodes 2,3 # doctest: +SKIP 23
Vartype Properties¶
QUBO (binary-valued variables) and Ising (spin-valued variables) instances of a BQM.
BinaryQuadraticModel.binary |
An instance of the QUBO model subclass of the BinaryQuadraticModel superclass (a BQM with binary variables). |
BinaryQuadraticModel.spin |
An instance of the Ising model subclass of the BinaryQuadraticModel superclass (a BQM with spin variables). |
Methods¶
BinaryQuadraticModel.empty (vartype) |
Create an empty binary quadratic model. |
BinaryQuadraticModel.add_variable (v, bias[, …]) |
Add variable v and/or its bias to a binary quadratic model. |
BinaryQuadraticModel.add_variables_from (linear) |
Add variables and/or linear biases to a binary quadratic model. |
BinaryQuadraticModel.add_interaction (u, v, bias) |
Add an interaction and/or quadratic bias to a binary quadratic model. |
BinaryQuadraticModel.add_interactions_from (…) |
Add interactions and/or quadratic biases to a binary quadratic model. |
BinaryQuadraticModel.add_offset (offset) |
Add specified value to the offset of a binary quadratic model. |
BinaryQuadraticModel.remove_variable (v) |
Remove variable v and all its interactions from a binary quadratic model. |
BinaryQuadraticModel.remove_variables_from (…) |
Remove specified variables and all of their interactions from a binary quadratic model. |
BinaryQuadraticModel.remove_interaction (u, v) |
Remove interaction of variables u, v from a binary quadratic model. |
BinaryQuadraticModel.remove_interactions_from (…) |
Remove all specified interactions from the binary quadratic model. |
BinaryQuadraticModel.remove_offset () |
Set the binary quadratic model’s offset to zero. |
BinaryQuadraticModel.update (bqm[, ignore_info]) |
Update one binary quadratic model from another. |
BinaryQuadraticModel.contract_variables (u, v) |
Enforce u, v being the same variable in a binary quadratic model. |
BinaryQuadraticModel.fix_variable (v, value) |
Fix the value of a variable and remove it from a binary quadratic model. |
BinaryQuadraticModel.fix_variables (fixed) |
Fix the value of the variables and remove it from a binary quadratic model. |
BinaryQuadraticModel.flip_variable (v) |
Flip variable v in a binary quadratic model. |
BinaryQuadraticModel.normalize ([bias_range, …]) |
Normalizes the biases of the binary quadratic model such that they fall in the provided range(s), and adjusts the offset appropriately. |
BinaryQuadraticModel.relabel_variables (mapping) |
Relabel variables of a binary quadratic model as specified by mapping. |
BinaryQuadraticModel.scale (scalar[, …]) |
Multiply by the specified scalar all the biases and offset of a binary quadratic model. |
BinaryQuadraticModel.change_vartype (**kwargs) |
Create a binary quadratic model with the specified vartype. |
BinaryQuadraticModel.copy () |
Create a copy of a binary quadratic model. |
BinaryQuadraticModel.energy (sample) |
Determine the energy of the specified sample of a binary quadratic model. |
BinaryQuadraticModel.energies (samples_like) |
Determine the energies of the given samples. |
BinaryQuadraticModel.from_coo (obj[, vartype]) |
Deserialize a binary quadratic model from a COOrdinate_ format encoding. |
BinaryQuadraticModel.from_ising (h, J[, offset]) |
Create a binary quadratic model from an Ising problem. |
BinaryQuadraticModel.from_networkx_graph (G) |
Create a binary quadratic model from a NetworkX graph. |
BinaryQuadraticModel.from_numpy_matrix (mat) |
Create a binary quadratic model from a NumPy array. |
BinaryQuadraticModel.from_numpy_vectors (…) |
Create a binary quadratic model from vectors. |
BinaryQuadraticModel.from_qubo (Q[, offset]) |
Create a binary quadratic model from a QUBO model. |
BinaryQuadraticModel.from_pandas_dataframe (bqm_df) |
Create a binary quadratic model from a QUBO model formatted as a pandas DataFrame. |
BinaryQuadraticModel.from_serializable (obj) |
Deserialize a binary quadratic model. |
BinaryQuadraticModel.to_coo ([fp, vartype_header]) |
Serialize the binary quadratic model to a COOrdinate_ format encoding. |
BinaryQuadraticModel.to_ising () |
Converts a binary quadratic model to Ising format. |
BinaryQuadraticModel.to_networkx_graph ([…]) |
Convert a binary quadratic model to NetworkX graph format. |
BinaryQuadraticModel.to_numpy_matrix ([…]) |
Convert a binary quadratic model to NumPy 2D array. |
BinaryQuadraticModel.to_numpy_vectors ([…]) |
Convert a binary quadratic model to numpy arrays. |
BinaryQuadraticModel.to_qubo () |
Convert a binary quadratic model to QUBO format. |
BinaryQuadraticModel.to_pandas_dataframe () |
Convert a binary quadratic model to pandas DataFrame format. |
BinaryQuadraticModel.to_serializable ([…]) |
Convert the binary quadratic model to a serializable object. |
Alias¶
-
BQM
¶ Alias for
BinaryQuadraticModel
alias of
dimod.binary_quadratic_model.BinaryQuadraticModel
BQM Generators¶
Chimera Structured¶
chimera_anticluster (*args, **kwargs) |
Generate an anticluster problem on a Chimera lattice. |
Constraints¶
combinations (n, k[, strength, vartype]) |
Generate a bqm that is minimized when k of n variables are selected. |
Frustrated Cluster Loops¶
frustrated_loop (*args, **kwargs) |
Generate a frustrated loop problem. |
BQM Functions¶
Functional interface to BQM methods and assorted utilities.
Roof-duality¶
fix_variables (bqm[, sampling_mode]) |
Determine assignments for some variables of a binary quadratic model. |
Traversal¶
connected_components (bqm) |
Yields sets of connected variables. |
bfs_variables (bqm, source) |
Yields variables in breadth-first search order. |
Samplers and Composites¶
Samplers¶
The dimod package includes several example samplers.
Contents
Exact Solver¶
A solver that calculates the energy of all possible samples.
Note
This sampler is designed for use in testing. Because it calculates the energy for every possible sample, it is very slow.
-
class
ExactSolver
[source]¶ A simple exact solver for testing and debugging code using your local CPU.
Notes
This solver becomes slow for problems with 18 or more variables.
Examples
This example solves a two-variable Ising model.
>>> h = {'a': -0.5, 'b': 1.0} >>> J = {('a', 'b'): -1.5} >>> sampleset = dimod.ExactSolver().sample_ising(h, J) >>> print(sampleset) a b energy num_oc. 0 -1 -1 -2.0 1 2 +1 +1 -1.0 1 1 +1 -1 0.0 1 3 -1 +1 3.0 1 ['SPIN', 4 rows, 4 samples, 2 variables]
This example solves a two-variable QUBO.
>>> Q = {('a', 'b'): 2.0, ('a', 'a'): 1.0, ('b', 'b'): -0.5} >>> sampleset = dimod.ExactSolver().sample_qubo(Q)
This example solves a two-variable binary quadratic model
>>> bqm = dimod.BinaryQuadraticModel({'a': 1.5}, {('a', 'b'): -1}, 0.0, 'SPIN') >>> sampleset = dimod.ExactSolver().sample(bqm)
ExactSolver.sample (bqm) |
Sample from a binary quadratic model. |
ExactSolver.sample_ising (h, J, **parameters) |
Sample from an Ising model using the implemented sample method. |
ExactSolver.sample_qubo (Q, **parameters) |
Sample from a QUBO using the implemented sample method. |
Null Sampler¶
A sampler that always returns an empty sample set.
-
class
NullSampler
(parameters=None)[source]¶ A sampler that always returns an empty sample set.
This sampler is useful for writing unit tests where the result is not important.
Parameters: parameters (iterable/dict, optional) – If provided, sets the parameters accepted by the sample methods. The values given in these parameters are ignored. Examples
>>> bqm = dimod.BinaryQuadraticModel.from_qubo({('a', 'b'): 1}) >>> sampler = dimod.NullSampler() >>> sampleset = sampler.sample(bqm) >>> len(sampleset) 0
Setting additional parameters for the null sampler.
>>> bqm = dimod.BinaryQuadraticModel.from_qubo({('a', 'b'): 1}) >>> sampler = dimod.NullSampler(parameters=['a']) >>> sampleset = sampler.sample(bqm, a=5)
NullSampler.parameters |
Keyword arguments accepted by the sampling methods |
NullSampler.sample (bqm, **kwargs) |
Return an empty sample set. |
NullSampler.sample_ising (h, J, **parameters) |
Sample from an Ising model using the implemented sample method. |
NullSampler.sample_qubo (Q, **parameters) |
Sample from a QUBO using the implemented sample method. |
Random Sampler¶
A sampler that gives random samples.
RandomSampler.parameters |
Keyword arguments accepted by the sampling methods. |
RandomSampler.sample (bqm[, num_reads]) |
Give random samples for a binary quadratic model. |
RandomSampler.sample_ising (h, J, **parameters) |
Sample from an Ising model using the implemented sample method. |
RandomSampler.sample_qubo (Q, **parameters) |
Sample from a QUBO using the implemented sample method. |
Simulated Annealing Sampler¶
A reference implementation of a simulated annealing sampler.
neal.sampler.SimulatedAnnealingSampler
is a more performant implementation of simulated annealing you can use for
solving problems.
SimulatedAnnealingSampler.parameters |
Keyword arguments accepted by the sampling methods. |
SimulatedAnnealingSampler.sample (bqm[, …]) |
Sample from low-energy spin states using simulated annealing. |
SimulatedAnnealingSampler.sample_ising (h, J, …) |
Sample from an Ising model using the implemented sample method. |
SimulatedAnnealingSampler.sample_qubo (Q, …) |
Sample from a QUBO using the implemented sample method. |
Composites¶
The dimod package includes several example composed samplers.
Connected Components Composite¶
A composite that breaks the problem into sub-problems corresponding to the connected components of the binary quadratic model graph before sending to its child sampler.
-
class
ConnectedComponentsComposite
(child_sampler)[source]¶ Composite to decompose a problem to the connected components and solve each.
Connected components of a bqm graph are computed (if not provided), and each subproblem is passed to the child sampler. Returned samples from each child sampler are merged. Only the best solution of each response is pick and merge with others (i.e. this composite returns a single solution).
Parameters: sampler ( dimod.Sampler
) – A dimod samplerExamples
This example uses
ConnectedComponentsComposite
to instantiate a composed sampler that submits a simple Ising problem to a sampler. The composed sampler finds the connected components and solves each.>>> h = {1: -1.3, 2: 2.3, 3:-1.2, 4: -0.5} >>> J = {(1, 4): -0.6, (1, 3): 0.6, (3, 4): 1.0, (2, 3): -1.0} >>> sampler = dimod.ConnectedComponentsComposite(dimod.ExactSolver()) >>> sampleset = sampler.sample_ising(h, J)
ConnectedComponentsComposite.child |
The child sampler. |
ConnectedComponentsComposite.children |
|
ConnectedComponentsComposite.parameters |
|
ConnectedComponentsComposite.properties |
ConnectedComponentsComposite.sample (bqm[, …]) |
Sample from the provided binary quadratic model. |
ConnectedComponentsComposite.sample_ising (h, …) |
Sample from an Ising model using the implemented sample method. |
ConnectedComponentsComposite.sample_qubo (Q, …) |
Sample from a QUBO using the implemented sample method. |
Clip Composite¶
A composite that clips problem variables below and above threshold. if lower and upper bounds is not given it does nothing.
-
class
ClipComposite
(child_sampler)[source]¶ Composite to clip variables of a problem
Clips the variables of a bqm and modifies linear and quadratic terms accordingly.
Parameters: sampler ( dimod.Sampler
) – A dimod samplerExamples
This example uses
ClipComposite
to instantiate a composed sampler that submits a simple Ising problem to a sampler. The composed sampler clips linear and quadratic biases as indicated by options.>>> h = {'a': -4.0, 'b': -4.0} >>> J = {('a', 'b'): 3.2} >>> sampler = dimod.ClipComposite(dimod.ExactSolver()) >>> response = sampler.sample_ising(h, J, lower_bound=-2.0, upper_bound=2.0)
ClipComposite.child |
The child sampler. |
ClipComposite.children |
|
ClipComposite.parameters |
|
ClipComposite.properties |
ClipComposite.sample (bqm[, lower_bound, …]) |
Clip and sample from the provided binary quadratic model. |
ClipComposite.sample_ising (h, J, **parameters) |
Sample from an Ising model using the implemented sample method. |
ClipComposite.sample_qubo (Q, **parameters) |
Sample from a QUBO using the implemented sample method. |
Fixed Variable Composite¶
A composite that fixes the variables provided and removes them from the binary quadratic model before sending to its child sampler.
-
class
FixedVariableComposite
(child_sampler)[source]¶ Composite to fix variables of a problem to provided.
Fixes variables of a bqm and modifies linear and quadratic terms accordingly. Returned samples include the fixed variable
Parameters: sampler ( dimod.Sampler
) – A dimod samplerExamples
This example uses
FixedVariableComposite
to instantiate a composed sampler that submits a simple Ising problem to a sampler. The composed sampler fixes a variable and modifies linear and quadratic biases according.>>> h = {1: -1.3, 4: -0.5} >>> J = {(1, 4): -0.6} >>> sampler = dimod.FixedVariableComposite(dimod.ExactSolver()) >>> sampleset = sampler.sample_ising(h, J, fixed_variables={1: -1})
FixedVariableComposite.child |
The child sampler. |
FixedVariableComposite.children |
|
FixedVariableComposite.parameters |
|
FixedVariableComposite.properties |
FixedVariableComposite.sample (bqm[, …]) |
Sample from the provided binary quadratic model. |
FixedVariableComposite.sample_ising (h, J, …) |
Sample from an Ising model using the implemented sample method. |
FixedVariableComposite.sample_qubo (Q, …) |
Sample from a QUBO using the implemented sample method. |
Roof Duality Composite¶
A composite that uses the roof duality algorithm [1] [2] to fix some variables in the binary quadratic model before passing it on to its child sampler.
[1] | Boros, E., P.L. Hammer, G. Tavares. Preprocessing of Unconstrained Quadratic Binary Optimization. Rutcor Research Report 10-2006, April, 2006. |
[2] | Boros, E., P.L. Hammer. Pseudo-Boolean optimization. Discrete Applied Mathematics 123, (2002), pp. 155-225 |
-
class
RoofDualityComposite
(child_sampler)[source]¶ Uses roof duality to assign some variables before invoking child sampler.
Uses the
fix_variables()
function to determine variable assignments, then fixes them before calling the child sampler. Returned samples include the fixed variables.Parameters: child ( dimod.Sampler
) – A dimod sampler. Used to sample the bqm after variables have been fixed.
RoofDualityComposite.child |
The child sampler. |
RoofDualityComposite.children |
|
RoofDualityComposite.parameters |
|
RoofDualityComposite.properties |
RoofDualityComposite.sample (bqm[, sampling_mode]) |
Sample from the provided binary quadratic model. |
RoofDualityComposite.sample_ising (h, J, …) |
Sample from an Ising model using the implemented sample method. |
RoofDualityComposite.sample_qubo (Q, **parameters) |
Sample from a QUBO using the implemented sample method. |
Scale Composite¶
A composite that scales problem variables as directed. if scalar is not given calculates it based on quadratic and bias ranges.
-
class
ScaleComposite
(child_sampler)[source]¶ Composite to scale variables of a problem
Scales the variables of a bqm and modifies linear and quadratic terms accordingly.
Parameters: sampler ( dimod.Sampler
) – A dimod samplerExamples
This example uses
ScaleComposite
to instantiate a composed sampler that submits a simple Ising problem to a sampler. The composed sampler scales linear, quadratic biases and offset as indicated by options.>>> h = {'a': -4.0, 'b': -4.0} >>> J = {('a', 'b'): 3.2} >>> sampler = dimod.ScaleComposite(dimod.ExactSolver()) >>> response = sampler.sample_ising(h, J, scalar=0.5, ... ignored_interactions=[('a','b')])
ScaleComposite.child |
The child sampler. |
ScaleComposite.children |
|
ScaleComposite.parameters |
|
ScaleComposite.properties |
ScaleComposite.sample (bqm[, scalar, …]) |
Scale and sample from the provided binary quadratic model. |
ScaleComposite.sample_ising (h, J[, offset, …]) |
Scale and sample from the problem provided by h, J, offset |
ScaleComposite.sample_qubo (Q, **parameters) |
Sample from a QUBO using the implemented sample method. |
Spin Reversal Transform Composite¶
On the D-Wave system, coupling \(J_{i,j}\) adds a small bias to qubits \(i\) and \(j\) due to leakage. This can become significant for chained qubits. Additionally, qubits are biased to some small degree in one direction or another. Applying a spin-reversal transform can improve results by reducing the impact of possible analog and systematic errors. A spin-reversal transform does not alter the Ising problem; the transform simply amounts to reinterpreting spin up as spin down, and visa-versa, for a particular spin.
-
class
SpinReversalTransformComposite
(child)[source]¶ Composite for applying spin reversal transform preprocessing.
Spin reversal transforms (or “gauge transformations”) are applied by flipping the spin of variables in the Ising problem. After sampling the transformed Ising problem, the same bits are flipped in the resulting sample [3].
Parameters: sampler – A dimod sampler object. Examples
This example composes a dimod ExactSolver sampler with spin transforms then uses it to sample an Ising problem.
>>> # Compose the sampler >>> base_sampler = dimod.ExactSolver() >>> composed_sampler = dimod.SpinReversalTransformComposite(base_sampler) >>> base_sampler in composed_sampler.children True >>> # Sample an Ising problem >>> response = composed_sampler.sample_ising({'a': -0.5, 'b': 1.0}, {('a', 'b'): -1}) >>> print(next(response.data())) # doctest: +SKIP Sample(sample={'a': 1, 'b': 1}, energy=-1.5)
References
[3] Andrew D. King and Catherine C. McGeoch. Algorithm engineering for a quantum annealing platform. https://arxiv.org/abs/1410.2628, 2014.
SpinReversalTransformComposite.child |
The child sampler. |
SpinReversalTransformComposite.children |
|
SpinReversalTransformComposite.parameters |
|
SpinReversalTransformComposite.properties |
SpinReversalTransformComposite.sample (bqm[, …]) |
Sample from the binary quadratic model. |
SpinReversalTransformComposite.sample_ising (h, …) |
Sample from an Ising model using the implemented sample method. |
SpinReversalTransformComposite.sample_qubo (Q, …) |
Sample from a QUBO using the implemented sample method. |
Structured Composite¶
A composite that structures a sampler.
-
class
StructureComposite
(sampler, nodelist, edgelist)[source]¶ Creates a structured composed sampler from an unstructured sampler.
Parameters: Examples
This example creates a composed sampler from the unstructure dimod ExactSolver sampler. The target structure is a square graph.
>>> import dimod ... >>> base_sampler = dimod.ExactSolver() >>> node_list = [0, 1, 2, 3] >>> edge_list = [(0, 1), (1, 2), (2, 3), (0, 3)] >>> structured_sampler = dimod.StructureComposite(base_sampler, node_list, edge_list) >>> linear = {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0} >>> quadratic = {(0, 1): 1.0, (1, 2): 1.0, (0, 3): 1.0, (2, 3): -1.0} >>> bqm = dimod.BinaryQuadraticModel(linear, quadratic, 1.0, dimod.Vartype.SPIN) >>> response = structured_sampler.sample(bqm) >>> print(next(response.data())) Sample(sample={0: 1, 1: -1, 2: -1, 3: -1}, energy=-1.0, num_occurrences=1) >>> # Try giving the composed sampler a non-square model >>> del quadratic[(0, 1)] >>> quadratic[(0, 2)] = 1.0 >>> bqm = dimod.BinaryQuadraticModel(linear, quadratic, 1.0, dimod.Vartype.SPIN) >>> try: response = structured_sampler.sample(bqm) # doctest: +SKIP ... except dimod.BinaryQuadraticModelStructureError as details: ... print(details) ... given bqm does not match the sampler's structure
StructureComposite.child |
The child sampler. |
StructureComposite.children |
|
StructureComposite.parameters |
|
StructureComposite.properties |
StructureComposite.sample (bqm, **kwargs) |
Sample from the binary quadratic model. |
StructureComposite.sample_ising (h, J, …) |
Sample from an Ising model using the implemented sample method. |
StructureComposite.sample_qubo (Q, **parameters) |
Sample from a QUBO using the implemented sample method. |
Tracking Composite¶
A composite that tracks inputs and outputs.
-
class
TrackingComposite
(child, copy=False)[source]¶ Composite that tracks inputs and outputs for debugging and testing.
Parameters: - child (
dimod.Sampler
) – A dimod sampler. - copy (bool, optional, default=False) – If True, the inputs/outputs are copied (with
copy.deepcopy()
) before they are stored. This is useful if the child sampler mutates the values.
Examples
>>> sampler = dimod.TrackingComposite(dimod.RandomSampler()) >>> sampleset = sampler.sample_ising({'a': -1}, {('a', 'b'): 1}, ... num_reads=5) >>> sampler.input OrderedDict([('h', {'a': -1}), ('J', {('a', 'b'): 1}), ('num_reads', 5)]) >>> sampleset == sampler.output True
If we make additional calls to the sampler, the most recent input/output are stored in
input
andoutput
respectively. However, all are tracked ininputs
andoutputs
.>>> sampleset = sampler.sample_qubo({('a', 'b'): 1}) >>> sampler.input OrderedDict([('Q', {('a', 'b'): 1})]) >>> sampler.inputs # doctest: +SKIP [OrderedDict([('h', {'a': -1}), ('J', {('a', 'b'): 1}), ('num_reads', 5)]), OrderedDict([('Q', {('a', 'b'): 1})])]
In the case that you want to nest the tracking composite, there are two patterns for retrieving the data
>>> from dimod import ScaleComposite, TrackingComposite, ExactSolver ... >>> sampler = ScaleComposite(TrackingComposite(ExactSolver())) >>> sampler.child.inputs # empty because we haven't called sample []
>>> intermediate_sampler = TrackingComposite(ExactSolver()) >>> sampler = ScaleComposite(intermediate_sampler) >>> intermediate_sampler.inputs []
- child (
TrackingComposite.input |
The most recent input to any sampling method. |
TrackingComposite.inputs |
All of the inputs to any sampling methods. |
TrackingComposite.output |
The most recent output of any sampling method. |
TrackingComposite.outputs |
All of the outputs from any sampling methods. |
TrackingComposite.parameters |
|
TrackingComposite.properties |
TrackingComposite.clear () |
Clear all the inputs/outputs. |
TrackingComposite.sample (*args, **kwargs) |
Sample from the child sampler and store the given inputs/outputs. |
TrackingComposite.sample_ising (*args, **kwargs) |
Sample from the child sampler and store the given inputs/outputs. |
TrackingComposite.sample_qubo (*args, **kwargs) |
Sample from the child sampler and store the given inputs/outputs. |
Truncate Composite¶
A composite that truncates the response based on options provided by the user.
-
class
TruncateComposite
(child_sampler, n, sorted_by='energy', aggregate=False)[source]¶ Composite to truncate the returned samples
Inherits from
dimod.ComposedSampler
.Post-processing is expensive and sometimes one might want to only treat the lowest energy samples. This composite layer allows one to pre-select the samples within a multi-composite pipeline
Parameters: - child_sampler (
dimod.Sampler
) – A dimod sampler - n (int) – Maximum number of rows in the returned sample set.
- sorted_by (str/None, optional, default='energy') – Selects the record field used to sort the samples before truncating. Note that sample order is maintained in the underlying array.
- aggregate (bool, optional, default=False) – If True, aggregate the samples before truncating.
Note
If aggregate is True
SampleSet.record.num_occurrences
are accumulated but no other fields are.- child_sampler (
TruncateComposite.child |
The child sampler. |
TruncateComposite.children |
|
TruncateComposite.parameters |
|
TruncateComposite.properties |
TruncateComposite.sample (bqm, **kwargs) |
Sample from the problem provided by bqm and truncate output. |
TruncateComposite.sample_ising (h, J, …) |
Sample from an Ising model using the implemented sample method. |
TruncateComposite.sample_qubo (Q, **parameters) |
Sample from a QUBO using the implemented sample method. |
Higher-Order Composites¶
The dimod package includes several example higher-order composed samplers.
HigherOrderComposite¶
Composites that convert binary quadratic model samplers into polynomial samplers or that work with binary polynomials.
Higher-order composites implement three sampling methods (similar to
Sampler
):
-
class
HigherOrderComposite
(child_sampler)[source]¶ Convert a binary quadratic model sampler to a binary polynomial sampler.
Energies of the returned samples do not include the penalties.
Parameters: sampler ( dimod.Sampler
) – A dimod samplerExample
This example uses
HigherOrderComposite
to instantiate a composed sampler that submits a simple Ising problem to a sampler. The composed sampler creates a bqm from a higher order problem.>>> sampler = dimod.HigherOrderComposite(dimod.ExactSolver()) >>> h = {0: -0.5, 1: -0.3, 2: -0.8} >>> J = {(0, 1, 2): -1.7} >>> sampleset = sampler.sample_hising(h, J, discard_unsatisfied=True) >>> sampleset.first # doctest: +SKIP Sample(sample={0: 1, 1: 1, 2: 1}, energy=-3.3, num_occurrences=1, penalty_satisfaction=True)
HigherOrderComposite.child |
The child sampler. |
HigherOrderComposite.children |
A list containing the wrapped sampler. |
HigherOrderComposite.parameters |
|
HigherOrderComposite.properties |
HigherOrderComposite.sample_poly (poly[, …]) |
Sample from the given binary polynomial. |
HigherOrderComposite.sample_hising (h, J, …) |
Sample from a higher-order Ising model. |
HigherOrderComposite.sample_hubo (H, **kwargs) |
Sample from a higher-order unconstrained binary optimization problem. |
PolyFixedVariableComposite¶
Composites that convert binary quadratic model samplers into polynomial samplers or that work with binary polynomials.
Higher-order composites implement three sampling methods (similar to
Sampler
):
-
class
PolyFixedVariableComposite
(child_sampler)[source]¶ Composite to fix variables of a problem to provided.
Fixes variables of a binary polynomial and modifies linear and k-local terms accordingly. Returned samples include the fixed variable
Parameters: sampler ( dimod.PolySampler
) – A dimod polynomial sampler.Examples
This example uses
PolyFixedVariableComposite
to instantiate a composed sampler that submits a simple high order Ising problem to a sampler. The composed sampler fixes a variable and modifies linear and k-local terms biases according.>>> h = {1: -1.3, 2: 1.2, 3: -3.4, 4: -0.5} >>> J = {(1, 4): -0.6, (1, 2, 3): 0.2, (1, 2, 3, 4): -0.1} >>> poly = dimod.BinaryPolynomial.from_hising(h, J, offset=0) >>> sampler = dimod.PolyFixedVariableComposite(dimod.ExactPolySolver()) >>> sampleset = sampler.sample_poly(poly, fixed_variables={3: -1, 4: 1})
PolyFixedVariableComposite.child |
The child sampler. |
PolyFixedVariableComposite.children |
|
PolyFixedVariableComposite.parameters |
|
PolyFixedVariableComposite.properties |
PolyFixedVariableComposite.sample_poly (poly) |
Sample from the provided binary quadratic model. |
PolyFixedVariableComposite.sample_hising (h, …) |
Sample from a higher-order Ising model. |
PolyFixedVariableComposite.sample_hubo (H, …) |
Sample from a higher-order unconstrained binary optimization problem. |
PolyScaleComposite¶
-
class
PolyScaleComposite
(child)[source]¶ Composite to scale biases of a binary polynomial.
Parameters: child ( PolySampler
) – A binary polynomial sampler.Examples
>>> linear = {'a': -4.0, 'b': -4.0} >>> quadratic = {('a', 'b'): 3.2, ('a', 'b', 'c'): 1} >>> sampler = dimod.PolyScaleComposite(dimod.HigherOrderComposite(dimod.ExactSolver())) >>> response = sampler.sample_hising(linear, quadratic, scalar=0.5, ... ignored_terms=[('a','b')])
PolyScaleComposite.child |
The child sampler. |
PolyScaleComposite.children |
The child sampler in a list |
PolyScaleComposite.parameters |
|
PolyScaleComposite.properties |
PolyScaleComposite.sample_poly (poly[, …]) |
Scale and sample from the given binary polynomial. |
PolyScaleComposite.sample_hising (h, J, **kwargs) |
Sample from a higher-order Ising model. |
PolyScaleComposite.sample_hubo (H, **kwargs) |
Sample from a higher-order unconstrained binary optimization problem. |
PolyTruncateComposite¶
-
class
PolyTruncateComposite
(child_sampler, n, sorted_by='energy', aggregate=False)[source]¶ Composite to truncate the returned samples
Post-processing is expensive and sometimes one might want to only treat the lowest energy samples. This composite layer allows one to pre-select the samples within a multi-composite pipeline
Parameters: - child_sampler (
dimod.PolySampler
) – A dimod binary polynomial sampler. - n (int) – Maximum number of rows in the returned sample set.
- sorted_by (str/None, optional, default='energy') – Selects the record field used to sort the samples before truncating. Note that sample order is maintained in the underlying array.
- aggregate (bool, optional, default=False) – If True, aggregate the samples before truncating.
Note
If aggregate is True
SampleSet.record.num_occurrences
are accumulated but no other fields are.- child_sampler (
PolyTruncateComposite.child |
The child sampler. |
PolyTruncateComposite.children |
|
PolyTruncateComposite.parameters |
|
PolyTruncateComposite.properties |
PolyTruncateComposite.sample_poly (poly, **kwargs) |
Sample from the binary polynomial and truncate output. |
PolyTruncateComposite.sample_hising (h, J, …) |
Sample from a higher-order Ising model. |
PolyTruncateComposite.sample_hubo (H, **kwargs) |
Sample from a higher-order unconstrained binary optimization problem. |
API for Samplers and Composites¶
You can create your own samplers with dimod’s Sampler
abstract base class (ABC)
providing complementary methods (e.g., ‘sample_qubo’ if only ‘sample_ising’ is implemented),
consistent responses, etc.
Properties of dimod Sampler Abstract Base Classes¶
The following table describes the inheritance, properties, methods/mixins of sampler ABCs.
ABC | Inherits from | Abstract Properties | Abstract Methods | Mixins |
---|---|---|---|---|
Sampler |
parameters , properties |
at least one of
sample() , sample_ising() , sample_qubo() |
sample() , sample_ising() , sample_qubo() |
|
Structured |
nodelist , edgelist |
structure , adjacency |
||
Composite |
children |
child |
||
ComposedSampler |
Sampler , Composite |
parameters , properties , children |
at least one of
sample() , sample_ising() , sample_qubo() |
sample() , sample_ising() , sample_qubo() ,
child |
PolySampler |
parameters , properties |
sample_poly() |
sample_hising() , sample_hubo() |
|
ComposedPolySampler |
PolySampler , Composite |
parameters , properties , children |
sample_poly() |
sample_hising() , sample_hubo() , child |
The table shows, for example, that the Sampler
class requires that you implement
the parameters
and properties
properties and at least
one sampler method; the class provides the unimplemented methods as mixins.
Creating a Sampler¶
The Sampler
abstract base class (see abc
) helps you create new
dimod samplers.
Any new dimod sampler must define a subclass of Sampler
that implements
abstract properties parameters
and properties
and one of the abstract methods sample()
, sample_ising()
,
or sample_qubo()
. The Sampler
class provides the complementary
methods as mixins and ensures consistent responses.
For example, the following steps show how to easily create a dimod sampler. It is
sufficient to implement a single method (in this example the sample_ising()
method)
to create a dimod sampler with the Sampler
class.
class LinearIsingSampler(dimod.Sampler):
def sample_ising(self, h, J):
sample = linear_ising(h, J)
energy = dimod.ising_energy(sample, h, J)
return dimod.SampleSet.from_samples([sample], energy=[energy]})
@property
def properties(self):
return dict()
@property
def parameters(self):
return dict()
For this example, the implemented sampler sample_ising()
can be based on
a simple placeholder function, which returns a sample that minimizes the linear terms:
def linear_ising(h, J):
sample = {}
for v in h:
if h[v] < 0:
sample[v] = +1
else:
sample[v] = -1
return sample
The Sampler
ABC provides the other sample methods “for free”
as mixins.
sampler = LinearIsingSampler()
response = sampler.sample_ising({'a': -1}, {}) # Implemented by class LinearIsingSampler
response = sampler.sample_qubo({('a', 'a'): 1}) # Mixin provided by Sampler class
response = sampler.sample(BinaryQuadraticModel.from_ising({'a': -1}, {})) # Mixin provided by Sampler class
Below is a more complex version of the same sampler, where the properties
and
parameters
properties return non-empty dicts.
class FancyLinearIsingSampler(dimod.Sampler):
def __init__(self):
self._properties = {'description': 'a simple sampler that only considers the linear terms'}
self._parameters = {'verbose': []}
def sample_ising(self, h, J, verbose=False):
sample = linear_ising(h, J)
energy = dimod.ising_energy(sample, h, J)
if verbose:
print(sample)
return dimod.SampleSet.from_samples([sample], energy=[energy]})
@property
def properties(self):
return self._properties
@property
def parameters(self):
return self._parameters
-
class
Sampler
[source]¶ Abstract base class for dimod samplers.
Provides all methods
sample()
,sample_ising()
,sample_qubo()
assuming at least one is implemented.
Sampler.parameters |
A dict where keys are the keyword parameters accepted by the sampler methods and values are lists of the properties relevent to each parameter. |
Sampler.properties |
A dict containing any additional information about the sampler. |
Sampler.sample (bqm, **parameters) |
Sample from a binary quadratic model. |
Sampler.sample_ising (h, J, **parameters) |
Sample from an Ising model using the implemented sample method. |
Sampler.sample_qubo (Q, **parameters) |
Sample from a QUBO using the implemented sample method. |
Creating a Composed Sampler¶
Samplers can be composed. The composite pattern allows layers of pre- and post-processing to be applied to binary quadratic programs without needing to change the underlying sampler implementation.
We refer to these layers as composites. Each composed sampler must include at least one sampler, and possibly many composites.
Each composed sampler is itself a dimod sampler with all of the included methods and parameters. In this way complex samplers can be constructed.
The dimod ComposedSampler
abstract base class inherits from Sampler
class
its abstract methods, properties, and mixins (for example, a sample_Ising method) and from
Composite
class the children property and child mixin (children being a list of
supported samplers with child providing the first).
Examples
The dimod package’s spin_transform.py reference example creates a composed sampler, SpinReversalTransformComposite(Sampler, Composite), that performs spin reversal transforms (“gauge transformations”) as a preprocessing step for a given sampler. The reference example implements the pseudocode below:
class SpinReversalTransformComposite(Sampler, Composite):
# Updates to inherited sampler properties and parameters
# Definition of the composite's children (i.e., supported samplers):
children = None
def __init__(self, child):
self.children = [child]
# The composite's implementation of spin-transformation functionality:
def sample(self, bqm, num_spin_reversal_transforms=2, spin_reversal_variables=None, **kwargs):
response = None
# Preprocessing code that includes instantiation of a sampler:
# flipped_response = self.child.sample(bqm, **kwargs)
return response
Given a sampler, sampler1, the composed sampler is used as any dimod sampler. For example, the composed sampler inherits an Ising sampling method:
>>> composed_sampler = dimod.SpinReversalTransformComposite(sampler1) # doctest: +SKIP
>>> h = {0: -1, 1: 1} # doctest: +SKIP
>>> response = composed_sampler.sample_ising(h, {}) # doctest: +SKIP
-
class
Composite
[source]¶ Abstract base class for dimod composites.
Provides the
child
mixin property and defines thechildren
abstract property to be implemented. These define the supported samplers for the composed sampler.
Composite.children |
List of child samplers that that are used by this composite. |
Composite.child |
The child sampler. |
Creating a Structured Sampler¶
A structured sampler can only sample from binary quadratic models with a specific graph.
For structured samplers you must implement the nodelist
and edgelist
properties. The Structured
abstract base class
provides access to the structure
and adjacency
properties as well as any method or properties required by the Sampler
abstract
base class. The bqm_structured
decorator verifies that any given binary quadratic
model conforms to the supported structure.
Examples
This simple example shows a structured sampler that can only sample from a binary quadratic model with two variables and one interaction.
class TwoVariablesSampler(dimod.Sampler, dimod.Structured):
@property
def nodelist(self):
return [0, 1]
@property
def edgelist(self):
return [(0, 1)]
@property
def properties(self):
return dict()
@property
def parameters(self):
return dict()
@dimod.decorators.bqm_structured
def sample(self, bqm):
# All bqm's passed in will be a subgraph of the sampler's structure
variable_list = list(bqm.linear)
samples = []
energies = []
for values in itertools.product(bqm.vartype.value, repeat=len(bqm)):
sample = dict(zip(variable_list, values))
samples.append(sample)
energies.append(bqm.energy(sample))
return dimod.SampleSet.from_samples(samples, bqm.Vartype, energies)
return response
-
class
Structured
[source]¶ The abstract base class for dimod structured samplers.
Provides the
Structured.adjacency
andStructured.structure
properties.Abstract properties
nodelist
andedgelist
must be implemented.
Structured.nodelist |
Nodes/variables allowed by the sampler. |
Structured.edgelist |
Edges/interactions allowed by the sampler in the form [(u, v), …]. |
Structured.adjacency |
Adjacency structure formatted as a dict, where keys are the nodes of the structured sampler and values are sets of all adjacent nodes for each key node. |
Structured.structure |
Structure of the structured sampler formatted as a namedtuple , Structure(nodelist, edgelist, adjacency), where the 3-tuple values are the nodelist , edgelist and adjacency attributes. |
Creating a Binary Polynomial Sampler¶
Samplers that handle binary polynomials: problems with binary variables that are not constrained to quadratic interactions.
-
class
PolySampler
[source]¶ Sampler that supports binary polynomials.
Binary polynomials are an extension of binary quadratic models that allow higher-order interactions.
PolySampler.parameters |
A dict where keys are the keyword parameters accepted by the sampler methods and values are lists of the properties relevant to each parameter. |
PolySampler.properties |
A dict containing any additional information about the sampler. |
PolySampler.sample_poly (polynomial, **kwargs) |
Sample from a higher-order polynomial. |
PolySampler.sample_hising (h, J, **kwargs) |
Sample from a higher-order Ising model. |
PolySampler.sample_hubo (H, **kwargs) |
Sample from a higher-order unconstrained binary optimization problem. |
Creating a Composed Binary Polynomial Sampler¶
-
class
ComposedPolySampler
[source]¶ Abstract base class for dimod composed polynomial samplers.
Inherits from
PolySampler
andComposite
.
Samples¶
dimod samplers sample from a problem’s objective function, such
as a BQM, and return an iterable of samples contained in a SampleSet
class.
In addition to containing the returned solutions and some additional
information, and providing methods to work with the solutions, SampleSet
is also used, for example, by dwave-hybrid,
which iterates sets of samples through samplers to solve arbitrary QUBOs. dimod
provides functionality for creating and manipulating samples.
sample_like Objects¶
as_samples (samples_like[, dtype, copy, order]) |
Convert a samples_like object to a NumPy array and list of labels. |
SampleSet¶
-
class
SampleSet
(**kwargs)[source]¶ Samples and any other data returned by dimod samplers.
Parameters: - record (
numpy.recarray
) – A NumPy record array. Must have ‘sample’, ‘energy’ and ‘num_occurrences’ as fields. The ‘sample’ field should be a 2D NumPy array where each row is a sample and each column represents the value of a variable. - variables (iterable) – An iterable of variable labels, corresponding to columns in record.samples.
- info (dict) – Information about the
SampleSet
as a whole, formatted as a dict. - vartype (
Vartype
/str/set) –Variable type for the
SampleSet
. Accepted input values:Vartype.SPIN
,'SPIN'
,{-1, 1}
Vartype.BINARY
,'BINARY'
,{0, 1}
Examples
This example creates a SampleSet out of a samples_like object (a NumPy array).
>>> import dimod >>> import numpy as np ... >>> dimod.SampleSet.from_samples(np.ones(5, dtype='int8'), 'BINARY', 0) # doctest: +SKIP SampleSet(rec.array([([1, 1, 1, 1, 1], 0, 1)], ... dtype=[('sample', 'i1', (5,)), ('energy', '<i4'), ('num_occurrences', '<i4')]), ... [0, 1, 2, 3, 4], {}, 'BINARY')
- record (
Properties¶
SampleSet.first |
Sample with the lowest-energy. |
SampleSet.info |
Dict of information about the SampleSet as a whole. |
SampleSet.record |
numpy.recarray containing the samples, energies, number of occurences, and other sample data. |
SampleSet.variables |
VariableIndexView of variable labels. |
SampleSet.vartype |
Vartype of the samples. |
Methods¶
SampleSet.aggregate () |
Create a new SampleSet with repeated samples aggregated. |
SampleSet.append_variables (samples_like[, …]) |
Create a new sampleset with the given variables and values. |
SampleSet.change_vartype (**kwargs) |
Return the SampleSet with the given vartype. |
SampleSet.copy () |
Create a shallow copy. |
SampleSet.data ([fields, sorted_by, name, …]) |
Iterate over the data in the SampleSet . |
SampleSet.done () |
Return True if a pending computation is done. |
SampleSet.from_future (future[, result_hook]) |
Construct a SampleSet referencing the result of a future computation. |
SampleSet.from_samples (samples_like, …[, …]) |
Build a SampleSet from raw samples. |
SampleSet.from_samples_bqm (samples_like, …) |
Build a sample set from raw samples and a binary quadratic model. |
SampleSet.from_serializable (obj) |
Deserialize a SampleSet . |
SampleSet.lowest ([rtol, atol]) |
Return a sample set containing the lowest-energy samples. |
SampleSet.resolve () |
Ensure that the sampleset is resolved if constructed from a future. |
SampleSet.relabel_variables (mapping[, inplace]) |
Relabel the variables of a SampleSet according to the specified mapping. |
SampleSet.samples ([n, sorted_by]) |
Return an iterable over the samples. |
SampleSet.slice (*slice_args, **kwargs) |
Create a new sample set with rows sliced according to standard Python slicing syntax. |
SampleSet.to_pandas_dataframe ([sample_column]) |
Convert a sample set to a Pandas DataFrame |
SampleSet.to_serializable ([use_bytes, …]) |
Convert a SampleSet to a serializable object. |
SampleSet.truncate (n[, sorted_by]) |
Create a new sample set with up to n rows. |
Utility Functions¶
concatenate (samplesets[, defaults]) |
Combine sample sets. |
Higher-Order Models¶
Sometimes it is nice to work with problems that are not restricted to quadratic interactions.
Binary Polynomials¶
-
class
BinaryPolynomial
(**kwargs)[source]¶ A polynomial with binary variables and real-valued coefficients.
Parameters: - poly (mapping/iterable) – Polynomial as a mapping of form {term: bias, …}, where term is a collection of variables and bias the associated bias. It can also be an iterable of 2-tuples (term, bias).
- vartype (
Vartype
/str/set) –Variable type for the binary quadratic model. Accepted input values:
Vartype.SPIN
,'SPIN'
,{-1, 1}
Vartype.BINARY
,'BINARY'
,{0, 1}
Examples
Binary polynomials can be constructed in many different ways. The following are all equivalent
>>> poly = dimod.BinaryPolynomial({'a': -1, 'ab': 1}, dimod.SPIN) >>> poly = dimod.BinaryPolynomial({('a',): -1, ('a', 'b'): 1}, dimod.SPIN) >>> poly = dimod.BinaryPolynomial([('a', -1), (('a', 'b'), 1)], dimod.SPIN) >>> poly = dimod.BinaryPolynomial({'a': -1, 'ab': .5, 'ba': .5}, dimod.SPIN)
Binary polynomials act a mutable mappings but the terms can be accessed with any sequence.
>>> poly = dimod.BinaryPolynomial({'a': -1, 'ab': 1}, dimod.BINARY) >>> poly['ab'] 1 >>> poly['ba'] 1 >>> poly[{'a', 'b'}] 1 >>> poly[('a', 'b')] 1 >>> poly['cd'] = 4 >>> poly['dc'] 4
Methods¶
BinaryPolynomial.copy () |
Create a shallow copy. |
BinaryPolynomial.energies (samples_like[, dtype]) |
The energies of the given samples. |
BinaryPolynomial.energy (sample_like[, dtype]) |
The energy of the given sample. |
BinaryPolynomial.from_hising (h, J[, offset]) |
Construct a binary polynomial from a higher-order Ising problem. |
BinaryPolynomial.from_hubo (H[, offset]) |
Construct a binary polynomial from a higher-order unconstrained binary optimization (HUBO) problem. |
BinaryPolynomial.normalize ([bias_range, …]) |
Normalizes the biases of the binary polynomial such that they fall in the provided range(s). |
BinaryPolynomial.relabel_variables (mapping) |
Relabel variables of a binary polynomial as specified by mapping. |
BinaryPolynomial.scale (scalar[, ignored_terms]) |
Multiply the polynomial by the given scalar. |
BinaryPolynomial.to_binary ([copy]) |
Return a binary polynomial over {0, 1} variables. |
BinaryPolynomial.to_hising () |
Construct a higher-order Ising problem from a binary polynomial. |
BinaryPolynomial.to_hubo () |
Construct a higher-order unconstrained binary optimization (HUBO) problem from a binary polynomial. |
BinaryPolynomial.to_spin ([copy]) |
Return a binary polynomial over {-1, +1} variables. |
Reducing to a Binary Quadratic Model¶
make_quadratic (poly, strength[, vartype, bqm]) |
Create a binary quadratic model from a higher order polynomial. |
Utilities¶
Contents
Energy Calculations¶
ising_energy (sample, h, J[, offset]) |
Calculate the energy for the specified sample of an Ising model. |
qubo_energy (sample, Q[, offset]) |
Calculate the energy for the specified sample of a QUBO model. |
Decorators¶
Decorators can be imported from the dimod.decorators
namespace. For
example:
>>> from dimod.decorators import vartype_argument
bqm_index_labels (f) |
Decorator to convert a BQM to index-labels and relabel the sample set output. |
bqm_index_labelled_input (…) |
Returns a decorator that ensures BQM variable labeling and specified sample_like inputs are index labeled and consistent. |
bqm_structured (f) |
Decorator to raise an error if the given BQM does not match the sampler’s structure. |
graph_argument (*arg_names, **options) |
Decorator to coerce given graph arguments into a consistent form. |
vartype_argument (*arg_names) |
Ensures the wrapped function receives valid vartype argument(s). |
Graph-like¶
child_structure_dfs (sampler[, seen]) |
Return the structure of a composed sampler using a depth-first search on its children. |
Serialization¶
JSON¶
JSON-encoding of dimod objects.
Examples
>>> import json
>>> from dimod.serialization.json import DimodEncoder, DimodDecoder
...
>>> bqm = dimod.BinaryQuadraticModel.from_ising({}, {('a', 'b'): -1})
>>> s = json.dumps(bqm, cls=DimodEncoder)
>>> new = json.loads(s, cls=DimodDecoder)
>>> bqm == new
True
>>> import json
>>> from dimod.serialization.json import DimodEncoder, DimodDecoder
...
>>> sampleset = dimod.SampleSet.from_samples({'a': -1, 'b': 1}, dimod.SPIN, energy=5)
>>> s = json.dumps(sampleset, cls=DimodEncoder)
>>> new = json.loads(s, cls=DimodDecoder)
>>> sampleset == new
True
>>> import json
>>> from dimod.serialization.json import DimodEncoder, DimodDecoder
...
>>> # now inside a list
>>> s = json.dumps([sampleset, bqm], cls=DimodEncoder)
>>> new = json.loads(s, cls=DimodDecoder)
>>> new == [sampleset, bqm]
True
-
class
DimodEncoder
(skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, encoding='utf-8', default=None)[source]¶ Subclass the JSONEncoder for dimod objects.
-
class
DimodDecoder
(*args, **kwargs)[source]¶ Subclass the JSONDecoder for dimod objects.
Uses
dimod_object_hook()
.
dimod_object_hook (obj) |
JSON-decoding for dimod objects. |
Testing¶
The testing subpackage contains functions for verifying and testing dimod
objects. Testing objects/functions can be imported from the dimod.testing
namespace. For example:
>>> from dimod.testing import assert_sampler_api
API Asserts¶
assert_composite_api (composed_sampler) |
Assert that an instantiated composed sampler exposes correct composite properties and methods. |
assert_sampler_api (sampler) |
Assert that an instantiated sampler exposes correct properties and methods. |
assert_structured_api (sampler) |
Assert that an instantiated structured sampler exposes correct composite properties and methods. |
Correctness Asserts¶
assert_bqm_almost_equal (actual, desired[, …]) |
Test if two binary quadratic models have almost equal biases. |
assert_response_energies (response, bqm[, …]) |
Assert that each sample in the given response has the correct energy. |
assert_sampleset_energies (sampleset, bqm[, …]) |
Assert that each sample in the given sample set has the correct energy. |
Vartype Conversion¶
ising_to_qubo (h, J[, offset]) |
Convert an Ising problem to a QUBO problem. |
qubo_to_ising (Q[, offset]) |
Convert a QUBO problem to an Ising problem. |
Vartype¶
Enumeration of valid variable types for binary quadratic models.
Examples
Vartype
is an Enum
. Each vartype has a value and
a name.
>>> vartype = dimod.SPIN
>>> vartype.name
'SPIN'
>>> vartype.value == {-1, +1}
True
>>> vartype = dimod.BINARY
>>> vartype.name
'BINARY'
>>> vartype.value == {0, 1}
True
The as_vartype()
function allows the user to provide several
convenient forms.
>>> from dimod import as_vartype
>>> as_vartype(dimod.SPIN) is dimod.SPIN
True
>>> as_vartype('SPIN') is dimod.SPIN
True
>>> as_vartype({-1, 1}) is dimod.SPIN
True
>>> as_vartype(dimod.BINARY) is dimod.BINARY
True
>>> as_vartype('BINARY') is dimod.BINARY
True
>>> as_vartype({0, 1}) is dimod.BINARY
True
Exceptions¶
-
exception
BinaryQuadraticModelSizeError
[source]¶ Raised when the binary quadratic model has too many variables
-
exception
BinaryQuadraticModelStructureError
[source]¶ Raised when the binary quadratic model does not fit the sampler
Bibliography¶
Installation¶
Compatible with Python 2 and 3:
pip install dimod
To install with optional components:
pip install dimod[all]
To install from source:
pip install -r requirements.txt
python setup.py install
Note that for an installation from source some functionality requires that your system have Boost C++ libraries installed.
License¶
Apache LicenseVersion 2.0, January 2004
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
- You must give any other recipients of the Work or Derivative Works a copy of this License; and
- You must cause any modified files to carry prominent notices stating that You changed the files; and
- You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
- If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets “[]” replaced with your own identifying information. (Don’t include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same “printed page” as the copyright notice for easier identification within third-party archives.Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.