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 nonempty 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.
Abstract Properties¶
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. 
Mixin Methods¶
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 postprocessing 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 spintransformation 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.
Abstract Properties¶
Composite.children 
List of child samplers that that are used by this composite. 
Mixin Properties¶
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.
Abstract Properties¶
Structured.nodelist 
Nodes/variables allowed by the sampler. 
Structured.edgelist 
Edges/interactions allowed by the sampler in the form [(u, v), …]. 
Mixin Properties¶
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 3tuple values are the nodelist and edgelist properties and adjacency() method. 
Creating a Binary Polynomial Sampler¶
It is possible to construct samplers that handle binary polynomials  problems that have binary variables but they are not constrained to quadratic interactions.

class
PolySampler
[source]¶ Sampler supports binary polynomials.
Binary polynomials are an extension of binary quadratic models that allow higherorder interactions.
Abstract Properties¶
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. 
Abstract Methods¶
PolySampler.sample_poly (polynomial, **kwargs) 
Sample from a higherorder polynomial. 
Mixin Methods¶
PolySampler.sample_hising (h, J, **kwargs) 
Sample from a higherorder Ising model. 
PolySampler.sample_hubo (H, **kwargs) 
Sample from a higherorder 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
.