def test_discard(self): sample0 = {0: -1, 1: -1, 2: +1} sample1 = {0: +1, 1: -1, 2: +1} samples = [sample0, sample1] embedding = {'a': {0, 1, 2}} bqm = dimod.BinaryQuadraticModel.from_ising({'a': 1}, {}) resp = dimod.Response.from_samples(samples, {'energy': [-1, 1]}, {}, dimod.SPIN) resp = dimod.unembed_response( resp, embedding, bqm, chain_break_method=dimod.embedding.discard) source_samples = list(resp) # no samples should be returned because they are all broken self.assertEqual(len(source_samples), 0) # now set up an embedding that works for one sample and not the other embedding = {'a': {0, 1}, 'b': {2}} bqm = dimod.BinaryQuadraticModel.from_ising({'a': 1}, {('a', 'b'): -1}) resp = dimod.Response.from_samples(samples, {'energy': [-1, 1]}, {}, dimod.SPIN) resp = dimod.unembed_response( resp, embedding, bqm, chain_break_method=dimod.embedding.discard) source_samples = list(resp) # only the first sample should be returned self.assertEqual(len(source_samples), 1) self.assertEqual(source_samples, [{'a': -1, 'b': +1}])
def test_unembed_response_with_discard_matrix_typical(self): h = {'a': .1, 'b': 0, 'c': 0} J = {('a', 'b'): 1, ('b', 'c'): 1.3, ('a', 'c'): -1} bqm = dimod.BinaryQuadraticModel.from_ising(h, J, offset=1.3) embedding = {'a': {0}, 'b': {1}, 'c': {2, 3}} embedded_bqm = dimod.embed_bqm(bqm, embedding, nx.cycle_graph(4), chain_strength=1) embedded_response = dimod.ExactSolver().sample(embedded_bqm) chain_break_method = dimod.embedding.discard response = dimod.unembed_response( embedded_response, embedding, bqm, chain_break_method=dimod.embedding.discard) self.assertEqual(len(embedded_response) / 2, len(response)) # half chains should be broken for sample, energy in response.data(['sample', 'energy']): self.assertEqual(bqm.energy(sample), energy)
def sample(self, bqm, chain_strength=1.0, chain_break_fraction=True, **parameters): """Sample from the provided binary quadratic model. Args: bqm (:obj:`dimod.BinaryQuadraticModel`): Binary quadratic model to be sampled from. chain_strength (float, optional, default=1.0): Magnitude of the quadratic bias (in SPIN-space) applied between variables to create chains. Note that the energy penalty of chain breaks is 2 * `chain_strength`. chain_break_fraction (bool, optional, default=True): If True, a ‘chain_break_fraction’ field is added to the unembedded response which report what fraction of the chains were broken before unembedding. **parameters: Parameters for the sampling method, specified by the child sampler. Returns: :class:`dimod.Response` Examples: This example uses :class:`.FixedEmbeddingComposite` to instantiate a composed sampler that submits an unstructured Ising problem to a D-Wave solver, selected by the user's default :std:doc:`D-Wave Cloud Client configuration file <cloud-client:reference/intro>`, while minor-embedding the problem's variables to physical qubits on the solver. >>> from dwave.system.samplers import DWaveSampler >>> from dwave.system.composites import FixedEmbeddingComposite >>> import dimod >>> sampler = FixedEmbeddingComposite(DWaveSampler(), {'a': [0, 4], 'b': [1, 5], 'c': [2, 6]}) >>> resp = sampler.sample_ising({'a': .5, 'c': 0}, {('a', 'c'): -1}) See `Ocean Glossary <https://docs.ocean.dwavesys.com/en/latest/glossary.html>`_ for explanations of technical terms in descriptions of Ocean tools. """ # solve the problem on the child system child = self.child # apply the embedding to the given problem to map it to the child sampler __, __, target_adjacency = child.structure # get the embedding embedding = self.embedding bqm_embedded = dimod.embed_bqm(bqm, embedding, target_adjacency, chain_strength=chain_strength) if 'initial_state' in parameters: parameters['initial_state'] = _embed_state(embedding, parameters['initial_state']) response = child.sample(bqm_embedded, **parameters) return dimod.unembed_response(response, embedding, source_bqm=bqm, chain_break_fraction=chain_break_fraction)
def test_energies_functional(self): h = {'a': .1, 'b': 0, 'c': 0} J = {('a', 'b'): 1, ('b', 'c'): 1.3, ('a', 'c'): -1} bqm = dimod.BinaryQuadraticModel.from_ising(h, J, offset=1.3) embedding = {'a': {0}, 'b': {1}, 'c': {2, 3}} embedded_bqm = dimod.embed_bqm(bqm, embedding, nx.cycle_graph(4), chain_strength=1) embedded_response = dimod.ExactSolver().sample(embedded_bqm) response = dimod.unembed_response(embedded_response, embedding, bqm) for sample, energy in response.data(['sample', 'energy']): self.assertEqual(bqm.energy(sample), energy)
def sample(self, bqm, chain_strength=1.0, **parameters): """Sample from the provided binary quadratic model. Args: bqm (:obj:`dimod.BinaryQuadraticModel`): Binary quadratic model to be sampled from. chain_strength (float, optional, default=1.0): Magnitude of the quadratic bias (in SPIN-space) applied between variables to create chains. Note that the energy penalty of chain breaks is 2 * `chain_strength`. **parameters: Parameters for the sampling method, specified by the child sampler. Returns: :class:`dimod.Response` Examples: This example uses :class:`.FixedEmbeddingComposite` to instantiate a composed sampler that submits an unstructured Ising problem to a D-Wave solver, selected by the user's default D-Wave Cloud Client configuration_ file, while minor-embedding the problem's variables to physical qubits on the solver. >>> from dwave.system.samplers import DWaveSampler >>> from dwave.system.composites import FixedEmbeddingComposite >>> import dimod >>> sampler = FixedEmbeddingComposite(DWaveSampler(), {'a': [0, 4], 'b': [1, 5], 'c': [2, 6]}) >>> resp = sampler.sample_ising({'a': .5, 'c': 0}, {('a', 'c'): -1}) """ # solve the problem on the child system child = self.child # apply the embedding to the given problem to map it to the child sampler __, __, target_adjacency = child.structure # get the embedding embedding = self._embedding bqm_embedded = dimod.embed_bqm(bqm, embedding, target_adjacency, chain_strength=chain_strength) response = child.sample(bqm_embedded, **parameters) return dimod.unembed_response(response, embedding, source_bqm=bqm)
def test_majority_vote_with_response(self): sample0 = {0: -1, 1: -1, 2: +1} sample1 = {0: +1, 1: -1, 2: +1} samples = [sample0, sample1] # now set up an embedding that works for one sample and not the other embedding = {'a': {0, 1, 2}} bqm = dimod.BinaryQuadraticModel.from_ising({'a': 1}, {}) resp = dimod.Response.from_dicts(samples, {'energy': [-1, 1]}) resp = dimod.unembed_response( resp, embedding, bqm, chain_break_method=dimod.embedding.majority_vote) # specify that majority vote should be used source_samples = list(resp) self.assertEqual(len(source_samples), 2) self.assertEqual(source_samples, [{'a': -1}, {'a': +1}])
def test_majority_vote(self): """should return the most common value in the chain""" sample0 = {0: -1, 1: -1, 2: +1} sample1 = {0: +1, 1: -1, 2: +1} samples = [sample0, sample1] embedding = {'a': {0, 1, 2}} bqm = dimod.BinaryQuadraticModel.from_ising({'a': 1}, {}) resp = dimod.Response.from_dicts(samples, {'energy': [-1, 1]}) resp = dimod.unembed_response( resp, embedding, bqm, chain_break_method=dimod.embedding.majority_vote) # specify that majority vote should be used source_samples = list(resp) self.assertEqual(source_samples, [{'a': -1}, {'a': +1}])
def test_embedding_superset(self): # source graph in the embedding is a superset of the bqm response = dimod.Response( np.rec.array([([-1, 1, -1, 1, -1, 1, -1, 1], -1.4, 1), ([-1, 1, -1, -1, -1, 1, -1, -1], -1.4, 1), ([+1, -1, -1, -1, 1, -1, -1, -1], -1.6, 1), ([+1, -1, -1, -1, 1, -1, -1, -1], -1.6, 1)], dtype=[('sample', 'i1', (8, )), ('energy', '<f8'), ('num_occurrences', '<i8')]), [0, 1, 2, 3, 4, 5, 6, 7], {}, 'SPIN') embedding = {0: {0, 4}, 1: {1, 5}, 2: {2, 6}, 3: {3, 7}} bqm = dimod.BinaryQuadraticModel.from_ising([.1, .2], {(0, 1): 1.5}, 0.0) unembedded = dimod.unembed_response(response, embedding, source_bqm=bqm) arr = np.rec.array([([-1, 1], -1.4, 1), ([-1, 1], -1.4, 1), ([+1, -1], -1.6, 1), ([+1, -1], -1.6, 1)], dtype=[('sample', 'i1', (2, )), ('energy', '<f8'), ('num_occurrences', '<i8')]) np.testing.assert_array_equal(arr, unembedded.record)
# In[ ]: # Return num_reads solutions (responses are in the D-Wave's graph of indexed qubits) kwargs = {} if 'num_reads' in sampler.parameters: kwargs['num_reads'] = 50 if 'answer_mode' in sampler.parameters: kwargs['answer_mode'] = 'histogram' response = sampler.sample(bqm_embedded, **kwargs) print("A solution indexed by qubits: \n", next(response.data(fields=['sample']))) # Sample(sample={1481: 0, 1482: 0, 1483: 1, 1484: 1, 1485: 0, 1487: 0, 1488: 0, 1489: 0, 1490: 0, 1491: 1, 1492: 1, 1493: 0, 1494: 1, 1495: 0, 1501: 0, 1506: 0, 1509: 0, 1608: 1, 1609: 1, 1610: 0, 1611: 1, 1612: 1, 1614: 1, 1615: 1, 1616: 1, 1617: 0, 1618: 0, 1619: 1, 1620: 1, 1621: 0, 1622: 1, 1623: 1, 1624: 1, 1625: 1, 1626: 1, 1627: 1, 1628: 1, 1629: 0, 1630: 1, 1631: 1, 1632: 1, 1634: 0, 1637: 0, 1638: 1, 1736: 1, 1737: 1, 1738: 0, 1739: 0, 1740: 0, 1741: 0, 1742: 1, 1743: 1, 1744: 1, 1745: 0, 1747: 1, 1748: 0, 1750: 1, 1751: 1, 1752: 1, 1753: 1, 1754: 1, 1755: 1, 1756: 0, 1757: 1, 1758: 1, 1759: 1, 1760: 1, 1864: 1, 1871: 1, 1879: 1, 1887: 1, 1888: 1, 1895: 1}) # Map back to the BQM's graph (nodes labeled "a0", "b0" etc,) response = dimod.unembed_response(response, embedding, source_bqm=bqm) print("\nThe solution in problem variables: \n", next(response.data(fields=['sample']))) # Sample(sample={'a0': 1, 'b0': 1, 'and0,1': 1, 'b1': 1, 'and0,2': 1, 'b2': 1, 'a1': 1, 'and1,0': 1, 'carry1,0': 1, 'and1,1': 1, 'carry1,1': 1, 'sum1,1': 0, 'and1,2': 1, 'a2': 0, 'and2,0': 0, 'carry2,0': 0, 'and2,1': 0, 'carry2,1': 1, 'sum2,1': 0, 'and2,2': 0, 'carry3,0': 0}) # ### Viewing the Solution # We need to convert back from binary numbers to integers. Because quantum computing is probabilistic, there is a slight chance that in many executions of this example, your execution might return an incorrect example. Rerunning the previous cell will most likely produce a correct answer. # In[ ]: from helpers.convert import to_base_ten # Select just just the first sample. sample = next(response.samples(n=1)) dict(sample) a, b = to_base_ten(sample)
def sample(self, bqm, chain_strength=1.0, chain_break_fraction=True, **parameters): """Sample from the provided binary quadratic model. Args: bqm (:obj:`dimod.BinaryQuadraticModel`): Binary quadratic model to be sampled from. chain_strength (float, optional, default=1.0): Magnitude of the quadratic bias (in SPIN-space) applied between variables to create chains. Note that the energy penalty of chain breaks is 2 * `chain_strength`. chain_break_fraction (bool, optional, default=True): If True, a ‘chain_break_fraction’ field is added to the unembedded response which report what fraction of the chains were broken before unembedding. **parameters: Parameters for the sampling method, specified by the child sampler. Returns: :class:`dimod.Response` Examples: This example uses :class:`.EmbeddingComposite` to instantiate a composed sampler that submits an unstructured Ising problem to a D-Wave solver, selected by the user's default :std:doc:`D-Wave Cloud Client configuration file <cloud-client:reference/intro>`, while minor-embedding the problem's variables to physical qubits on the solver. >>> from dwave.system.samplers import DWaveSampler >>> from dwave.system.composites import EmbeddingComposite >>> import dimod >>> sampler = EmbeddingComposite(DWaveSampler()) >>> h = {1: 1, 2: 2, 3: 3, 4: 4} >>> J = {(1, 2): 12, (1, 3): 13, (1, 4): 14, ... (2, 3): 23, (2, 4): 24, ... (3, 4): 34} >>> bqm = dimod.BinaryQuadraticModel.from_ising(h, J) >>> response = sampler.sample(bqm) >>> for sample in response.samples(): # doctest: +SKIP ... print(sample) ... {1: -1, 2: 1, 3: 1, 4: -1} See `Ocean Glossary <https://docs.ocean.dwavesys.com/en/latest/glossary.html>`_ for explanations of technical terms in descriptions of Ocean tools. """ # solve the problem on the child system child = self.child # apply the embedding to the given problem to map it to the child sampler __, target_edgelist, target_adjacency = child.structure # add self-loops to edgelist to handle singleton variables source_edgelist = list(bqm.quadratic) + [(v, v) for v in bqm.linear] # get the embedding embedding = minorminer.find_embedding(source_edgelist, target_edgelist) if bqm and not embedding: raise ValueError("no embedding found") bqm_embedded = dimod.embed_bqm(bqm, embedding, target_adjacency, chain_strength=chain_strength) if 'initial_state' in parameters: parameters['initial_state'] = _embed_state( embedding, parameters['initial_state']) response = child.sample(bqm_embedded, **parameters) return dimod.unembed_response( response, embedding, source_bqm=bqm, chain_break_fraction=chain_break_fraction)
def sample(self, bqm, chain_strength=1.0, **parameters): """Sample from the provided binary quadratic model. Args: bqm (:obj:`dimod.BinaryQuadraticModel`): Binary quadratic model to be sampled from. chain_strength (float, optional, default=1.0): Magnitude of the quadratic bias (in SPIN-space) applied between variables to create chains. Note that the energy penalty of chain breaks is 2 * `chain_strength`. **parameters: Parameters for the sampling method, specified by the child sampler. Returns: :class:`dimod.Response` Examples: This example uses :class:`.EmbeddingComposite` to instantiate a composed sampler that submits an unstructured Ising problem to a D-Wave solver, selected by the user's default D-Wave Cloud Client configuration_ file, while minor-embedding the problem's variables to physical qubits on the solver. >>> from dwave.system.samplers import DWaveSampler >>> from dwave.system.composites import EmbeddingComposite >>> import dimod >>> sampler = EmbeddingComposite(DWaveSampler()) >>> h = {1: 1, 2: 2, 3: 3, 4: 4} >>> J = {(1, 2): 12, (1, 3): 13, (1, 4): 14, ... (2, 3): 23, (2, 4): 24, ... (3, 4): 34} >>> bqm = dimod.BinaryQuadraticModel.from_ising(h, J) >>> response = sampler.sample(bqm) >>> for sample in response.samples(): # doctest: +SKIP ... print(sample) ... {1: -1, 2: 1, 3: 1, 4: -1} """ # solve the problem on the child system child = self.child # apply the embedding to the given problem to map it to the child sampler __, target_edgelist, target_adjacency = child.structure # add self-loops to edgelist to handle singleton variables source_edgelist = list(bqm.quadratic) + [(v, v) for v in bqm.linear] # get the embedding embedding = minorminer.find_embedding(source_edgelist, target_edgelist) if bqm and not embedding: raise ValueError("no embedding found") bqm_embedded = dimod.embed_bqm(bqm, embedding, target_adjacency, chain_strength=chain_strength) response = child.sample(bqm_embedded, **parameters) return dimod.unembed_response(response, embedding, source_bqm=bqm)
def factor(P, use_saved_embedding=True): #################################################################################################### # get circuit #################################################################################################### construction_start_time = time.time() validate_input(P, range(2 ** 6)) # get constraint satisfaction problem csp = dbc.factories.multiplication_circuit(3) # get binary quadratic model bqm = dbc.stitch(csp, min_classical_gap=.1) # we know that multiplication_circuit() has created these variables p_vars = ['p0', 'p1', 'p2', 'p3', 'p4', 'p5'] # convert P from decimal to binary fixed_variables = dict(zip(reversed(p_vars), "{:06b}".format(P))) fixed_variables = {var: int(x) for(var, x) in fixed_variables.items()} # fix product qubits for var, value in fixed_variables.items(): bqm.fix_variable(var, value) log.debug('bqm construction time: %s', time.time() - construction_start_time) #################################################################################################### # run problem #################################################################################################### sample_time = time.time() # get QPU sampler sampler = DWaveSampler() _, target_edgelist, target_adjacency = sampler.structure if use_saved_embedding: # load a pre-calculated embedding from factoring.embedding import embeddings embedding = embeddings[sampler.solver.id] else: # get the embedding embedding = minorminer.find_embedding(bqm.quadratic, target_edgelist) if bqm and not embedding: raise ValueError("no embedding found") # apply the embedding to the given problem to map it to the sampler bqm_embedded = dimod.embed_bqm(bqm, embedding, target_adjacency, 3.0) # draw samples from the QPU kwargs = {} if 'num_reads' in sampler.parameters: kwargs['num_reads'] = 50 if 'answer_mode' in sampler.parameters: kwargs['answer_mode'] = 'histogram' response = sampler.sample(bqm_embedded, **kwargs) # convert back to the original problem space response = dimod.unembed_response(response, embedding, source_bqm=bqm) sampler.client.close() log.debug('embedding and sampling time: %s', time.time() - sample_time) #################################################################################################### # output results #################################################################################################### output = { "results": [], # { # "a": Number, # "b": Number, # "valid": Boolean, # "numOfOccurrences": Number, # "percentageOfOccurrences": Number # } "timing": { "actual": { "qpuProcessTime": None # microseconds } }, "numberOfReads": None } # we know that multiplication_circuit() has created these variables a_vars = ['a0', 'a1', 'a2'] b_vars = ['b0', 'b1', 'b2'] # histogram answer_mode should return counts for unique solutions if 'num_occurrences' not in response.data_vectors: response.data_vectors['num_occurrences'] = [1] * len(response) # should equal num_reads total = sum(response.data_vectors['num_occurrences']) results_dict = OrderedDict() for sample, num_occurrences in response.data(['sample', 'num_occurrences']): # convert A and B from binary to decimal a = b = 0 for lbl in reversed(a_vars): a = (a << 1) | sample[lbl] for lbl in reversed(b_vars): b = (b << 1) | sample[lbl] # aggregate results by unique A and B values (ignoring internal circuit variables) if (a, b, P) in results_dict: results_dict[(a, b, P)]["numOfOccurrences"] += num_occurrences results_dict[(a, b, P)]["percentageOfOccurrences"] = 100 * \ results_dict[(a, b, P)]["numOfOccurrences"] / total else: results_dict[(a, b, P)] = {"a": a, "b": b, "valid": a * b == P, "numOfOccurrences": num_occurrences, "percentageOfOccurrences": 100 * num_occurrences / total} output['results'] = list(results_dict.values()) output['numberOfReads'] = total if 'timing' in response.info: output['timing']['actual']['qpuProcessTime'] = response.info['timing']['qpu_access_time'] return output
def sample(self, bqm, **kwargs): """Sample from the provided binary quadratic model Args: bqm (:obj:`dimod.BinaryQuadraticModel`): Binary quadratic model to be sampled from. **kwargs: Optional keyword arguments for the sampling method, specified per solver. Returns: :class:`dimod.Response` Examples: This example uses :class:`.TilingComposite` to instantiate a composed sampler that submits a simple Ising problem of just two variables that map to qubits 0 and 1 on the D-Wave solver selected by the user's default D-Wave Cloud Client configuration_ file. (The simplicity of this example obviates the need for an embedding composite.) Because the problem fits in a single Chimera_ unit cell, it is tiled across the solver's entire Chimera graph, resulting in multiple samples. >>> from dwave.system.samplers import DWaveSampler >>> from dwave.system.composites import EmbeddingComposite >>> samplertile = TilingComposite(DWaveSampler(), 1, 1, 4) >>> response = sampler_tile.sample_ising({0: -1, 1: 1}, {}) >>> for sample in response.samples(): # doctest: +SKIP ... print(sample) ... {0: 1, 1: -1} {0: 1, 1: -1} {0: 1, 1: -1} {0: 1, 1: -1} {0: 1, 1: -1} {0: 1, 1: -1} {0: 1, 1: -1} {0: 1, 1: -1} >>> # Snipped above response for brevity .. _configuration: http://dwave-cloud-client.readthedocs.io/en/latest/#module-dwave.cloud.config .. _Chimera: http://dwave-system.readthedocs.io/en/latest/reference/intro.html#chimera """ # apply the embeddings to the given problem to tile it across the child sampler embedded_bqm = dimod.BinaryQuadraticModel.empty(bqm.vartype) __, __, target_adjacency = self.child.structure for embedding in self.embeddings: embedded_bqm.update(dimod.embed_bqm(bqm, embedding, target_adjacency)) # solve the problem on the child system response = self.child.sample(embedded_bqm, **kwargs) data_vectors = response.data_vectors.copy() source_response = None for embedding in self.embeddings: # filter for problem variables embedding = {v: chain for v, chain in embedding.items() if v in bqm.linear} tile_response = dimod.unembed_response(response, embedding, source_bqm=bqm) if source_response is None: source_response = tile_response source_response.info.update(response.info) # overwrite the info else: source_response.update(tile_response) return source_response
def sample(self, bqm, **kwargs): """Sample from the provided binary quadratic model Args: bqm (:obj:`dimod.BinaryQuadraticModel`): Binary quadratic model to be sampled from. **kwargs: Optional keyword arguments for the sampling method, specified per solver. Returns: :class:`dimod.Response` Examples: This example uses :class:`.TilingComposite` to instantiate a composed sampler that submits a simple Ising problem of just two variables that map to qubits 0 and 1 on the D-Wave solver selected by the user's default :std:doc:`D-Wave Cloud Client configuration file <cloud-client:reference/intro>`. (The simplicity of this example obviates the need for an embedding composite.) Because the problem fits in a single :std:doc:`Chimera <system:reference/intro>` unit cell, it is tiled across the solver's entire Chimera graph, resulting in multiple samples. >>> from dwave.system.samplers import DWaveSampler >>> from dwave.system.composites import EmbeddingComposite, TilingComposite >>> sampler = TilingComposite(DWaveSampler(), 1, 1, 4) >>> response = sampler.sample_ising({0: -1, 1: 1}, {}) >>> for sample in response.samples(): # doctest: +SKIP ... print(sample) ... {0: 1, 1: -1} {0: 1, 1: -1} {0: 1, 1: -1} {0: 1, 1: -1} {0: 1, 1: -1} {0: 1, 1: -1} {0: 1, 1: -1} {0: 1, 1: -1} >>> # Snipped above response for brevity See `Ocean Glossary <https://docs.ocean.dwavesys.com/en/latest/glossary.html>`_ for explanations of technical terms in descriptions of Ocean tools. """ # apply the embeddings to the given problem to tile it across the child sampler embedded_bqm = dimod.BinaryQuadraticModel.empty(bqm.vartype) __, __, target_adjacency = self.child.structure for embedding in self.embeddings: embedded_bqm.update( dimod.embed_bqm(bqm, embedding, target_adjacency)) # solve the problem on the child system tiled_response = self.child.sample(embedded_bqm, **kwargs) responses = [] for embedding in self.embeddings: embedding = { v: chain for v, chain in embedding.items() if v in bqm.linear } responses.append( dimod.unembed_response(tiled_response, embedding, bqm)) # stack the records record = np.rec.array(np.hstack((resp.record for resp in responses))) vartypes = set(resp.vartype for resp in responses) if len(vartypes) > 1: raise RuntimeError("inconsistent vartypes returned") vartype = vartypes.pop() info = {} for resp in responses: info.update(resp.info) labels = responses[0].variable_labels return dimod.Response(record, labels, info, vartype)
def sample(self, bqm, chain_strength=1.0, chain_break_fraction=True, **parameters): """Sample from the provided binary quadratic model. Also set parameters for handling a chain, the set of vertices in a target graph that represents a source-graph vertex; when a D-Wave system is the sampler, it is a set of qubits that together represent a variable of the binary quadratic model being minor-embedded. Args: bqm (:obj:`dimod.BinaryQuadraticModel`): Binary quadratic model to be sampled from. chain_strength (float, optional, default=1.0): Magnitude of the quadratic bias (in SPIN-space) applied between variables to create chains. The energy penalty of chain breaks is 2 * `chain_strength`. chain_break_fraction (bool, optional, default=True): If True, the unembedded response contains a ‘chain_break_fraction’ field that reports the fraction of chains broken before unembedding. **parameters: Parameters for the sampling method, specified by the child sampler. Returns: :class:`dimod.Response`: A `dimod` :obj:`~dimod.Response` object. Examples: This example submits an triangle-structured problem to a D-Wave solver, selected by the user's default :std:doc:`D-Wave Cloud Client configuration file <cloud-client:reference/intro>`, using a specified minor-embedding of the problem’s variables to physical qubits. >>> from dwave.system.samplers import DWaveSampler >>> from dwave.system.composites import FixedEmbeddingComposite >>> import dimod ... >>> sampler = FixedEmbeddingComposite(DWaveSampler(), {'a': [0, 4], 'b': [1, 5], 'c': [2, 6]}) >>> response = sampler.sample_ising({}, {'ab': 0.5, 'bc': 0.5, 'ca': 0.5}, chain_strength=2) >>> response.first # doctest: +SKIP Sample(sample={'a': 1, 'b': -1, 'c': 1}, energy=-0.5, num_occurrences=1, chain_break_fraction=0.0) See `Ocean Glossary <https://docs.ocean.dwavesys.com/en/latest/glossary.html>`_ for explanations of technical terms in descriptions of Ocean tools. """ # solve the problem on the child system child = self.child # apply the embedding to the given problem to map it to the child sampler __, __, target_adjacency = child.structure # get the embedding embedding = self.embedding bqm_embedded = dimod.embed_bqm(bqm, embedding, target_adjacency, chain_strength=chain_strength) if 'initial_state' in parameters: parameters['initial_state'] = _embed_state( embedding, parameters['initial_state']) response = child.sample(bqm_embedded, **parameters) return dimod.unembed_response( response, embedding, source_bqm=bqm, chain_break_fraction=chain_break_fraction)
def sample(self, bqm, apply_flux_bias_offsets=True, **kwargs): """Sample from the given Ising model. Args: h (list/dict): Linear biases of the Ising model. If a list, the list's indices are used as variable labels. J (dict of (int, int):float): Quadratic biases of the Ising model. apply_flux_bias_offsets (bool, optional): If True, use the calculated flux_bias offsets (if available). **kwargs: Optional keyword arguments for the sampling method, specified per solver. Examples: This example uses :class:`.VirtualGraphComposite` to instantiate a composed sampler that submits an Ising problem to a D-Wave solver selected by the user's default D-Wave Cloud Client configuration_ file. The problem represents a logical NOT gate using penalty function :math:`P = xy`, where variable x is the gate's input and y the output. This simple two-variable problem is manually minor-embedded to a single Chimera_ unit cell: each variable is represented by a chain of half the cell's qubits, x as qubits 0, 1, 4, 5, and y as qubits 2, 3, 6, 7. The chain strength is set to half the maximum allowed found from querying the solver's extended J range. In this example, the ten returned samples all represent valid states of the NOT gate. >>> from dwave.system.samplers import DWaveSampler >>> from dwave.system.composites import VirtualGraphComposite >>> embedding = {'x': {0, 4, 1, 5}, 'y': {2, 6, 3, 7}} >>> DWaveSampler().properties['extended_j_range'] # doctest: +SKIP [-2.0, 1.0] >>> sampler = VirtualGraphComposite(DWaveSampler(), embedding, chain_strength=1) # doctest: +SKIP >>> h = {} >>> J = {('x', 'y'): 1} >>> response = sampler.sample_ising(h, J, num_reads=10) # doctest: +SKIP >>> for sample in response.samples(): # doctest: +SKIP ... print(sample) ... {'y': -1, 'x': 1} {'y': 1, 'x': -1} {'y': -1, 'x': 1} {'y': -1, 'x': 1} {'y': -1, 'x': 1} {'y': 1, 'x': -1} {'y': 1, 'x': -1} {'y': 1, 'x': -1} {'y': -1, 'x': 1} {'y': 1, 'x': -1} .. _configuration: http://dwave-cloud-client.readthedocs.io/en/latest/#module-dwave.cloud.config .. _Chimera: http://dwave-system.readthedocs.io/en/latest/reference/intro.html#chimera """ # apply the embedding to the given problem to map it to the child sampler __, __, target_adjacency = self.child.structure embedding = self.embedding embedded_bqm = dimod.embed_bqm(bqm, self.embedding, target_adjacency, self.chain_strength) # solve the problem on the child system child = self.child if apply_flux_bias_offsets and self.flux_biases is not None: # If self.flux_biases is in the old format (list of lists) convert it to the new format (flat list). if isinstance(self.flux_biases[0], list): flux_bias_dict = dict(self.flux_biases) kwargs[FLUX_BIAS_KWARG] = [flux_bias_dict.get(v, 0.) for v in range(child.properties['num_qubits'])] else: kwargs[FLUX_BIAS_KWARG] = self.flux_biases assert len(kwargs[FLUX_BIAS_KWARG]) == child.properties['num_qubits'], \ "{} must have length {}, the solver's num_qubits."\ .format(FLUX_BIAS_KWARG, child.properties['num_qubits']) # Embed arguments providing initial states for reverse annealing, if applicable. kwargs = _embed_initial_state_kwargs(kwargs, self.embedding, self.child.structure[0]) response = child.sample(embedded_bqm, **kwargs) return dimod.unembed_response(response, embedding, source_bqm=bqm)
def sample(self, bqm, **kwargs): """Sample from the specified binary quadratic model. Args: bqm (:obj:`dimod.BinaryQuadraticModel`): Binary quadratic model to be sampled from. **kwargs: Optional keyword arguments for the sampling method, specified per solver. Returns: :class:`dimod.Response`: A `dimod` :obj:`~dimod.Response` object. Examples: This example submits a simple Ising problem of just two variables on a D-Wave system selected by the user's default :std:doc:`D-Wave Cloud Client configuration file <cloud-client:reference/intro>`. Because the problem fits in a single :term:`Chimera` unit cell, it is tiled across the solver's entire Chimera graph, resulting in multiple samples (the exact number depends on the working Chimera graph of the D-Wave system). >>> from dwave.system.samplers import DWaveSampler >>> from dwave.system.composites import EmbeddingComposite >>> from dwave.system.composites import EmbeddingComposite, TilingComposite ... >>> sampler = EmbeddingComposite(TilingComposite(DWaveSampler(), 1, 1, 4)) >>> response = sampler.sample_ising({},{('a', 'b'): 1}) >>> len(response) # doctest: +SKIP 246 See `Ocean Glossary <https://docs.ocean.dwavesys.com/en/latest/glossary.html>`_ for explanations of technical terms in descriptions of Ocean tools. """ # apply the embeddings to the given problem to tile it across the child sampler embedded_bqm = dimod.BinaryQuadraticModel.empty(bqm.vartype) __, __, target_adjacency = self.child.structure for embedding in self.embeddings: embedded_bqm.update( dimod.embed_bqm(bqm, embedding, target_adjacency)) # solve the problem on the child system tiled_response = self.child.sample(embedded_bqm, **kwargs) responses = [] for embedding in self.embeddings: embedding = { v: chain for v, chain in embedding.items() if v in bqm.linear } responses.append( dimod.unembed_response(tiled_response, embedding, bqm)) # stack the records record = np.rec.array(np.hstack((resp.record for resp in responses))) vartypes = set(resp.vartype for resp in responses) if len(vartypes) > 1: raise RuntimeError("inconsistent vartypes returned") vartype = vartypes.pop() info = {} for resp in responses: info.update(resp.info) labels = responses[0].variable_labels return dimod.Response(record, labels, info, vartype)