Samplers and Composites

dimod includes reference samplers and composites for processing quadratic (and higher order) models and refining sampling, and for testing your code during development.

Using Samplers

For an introduction to samplers and composites, see Concepts: Samplers and Composites. For descriptions of all supported samplers, see Samplers reference documentation.

Example: Using a Reference Sampler

To find solutions to the small four-node maximum cut BQM generated in the Quadratic Models: Unconstrained section, shown again in the figure below, you can use one of dimod’s reference samplers: its ExactSolver test sampler, for example, calculates the energy of all possible samples.

Four-node star graph

Star graph with four nodes.

>>> qubo = {(0, 0): -3, (1, 1): -1, (0, 1): 2, (2, 2): -1,
...         (0, 2): 2, (3, 3): -1, (0, 3): 2}
>>> dict_bqm = dimod.BQM.from_qubo(qubo)
>>> sampler_exact = dimod.ExactSolver()
>>> sampleset = sampler_exact.sample(dict_bqm)
>>> print(sampleset)
    0  1  2  3 energy num_oc.
1   1  0  0  0   -3.0       1
11  0  1  1  1   -3.0       1
2   1  1  0  0   -2.0       1
...
10  1  1  1  1    0.0       1
['BINARY', 16 rows, 16 samples, 4 variables]

Samplers can be composed. The composite pattern allows layers of pre- and post-processing to be applied to quadratic programs for a sampler implementation.

Example: Using a Composed Sampler

This example uses a composed sampler on the Boolean NOT Gate example detailed in the Getting Started documentation.

The StructureComposite composite enforces the shape of the binary quadratic model. In this case we only want to accept binary quadratic models with nodes labelled 'x', 'y', and 'z'.

>>> from dimod import ExactSolver, StructureComposite
>>> nodelist = ['x', 'y', 'z']
>>> edgelist = [('x', 'y'), ('x', 'z'), ('y', 'z')]
>>> composed_sampler = StructureComposite(ExactSolver(), nodelist, edgelist)
>>> Q = {('x', 'x'): -1, ('x', 'z'): 2, ('z', 'x'): 0, ('z', 'z'): -1}
>>> sampleset = composed_sampler.sample_qubo(Q)
>>> print(sampleset)
   x  z energy num_oc.
1  1  0   -1.0       1
3  0  1   -1.0       1
0  0  0    0.0       1
2  1  1    0.0       1
['BINARY', 4 rows, 4 samples, 2 variables]
>>> Q = {('a', 'a'): -1, ('a', 'b'): 2, ('b', 'a'): 0, ('b', 'b'): -1}
>>> try:
...     sampleset = composed_sampler.sample_qubo(Q)
... except ValueError:
...     print("incorrect structure!")
incorrect structure!

Creating Samplers

dimod provides an API for Samplers and Composites you can use to create your own dimod samplers and composed samplers.

Example: Creating a Sampler

This 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, **kwargs):
        kwargs = self.remove_unknown_kwargs(**kwargs)
        sample = linear_ising(h, J, **kwargs)  # Defined elsewhere
        energy = dimod.ising_energy(sample, h, J)
        return dimod.SampleSet.from_samples(sample, vartype=dimod.SPIN, 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.