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 test_embed_bqm_BINARY(self): Q = { ('a', 'a'): 0, ('a', 'b'): -1, ('b', 'b'): 0, ('c', 'c'): 0, ('b', 'c'): -1 } bqm = dimod.BinaryQuadraticModel.from_qubo(Q) embedding = {'a': {0}, 'b': {1}, 'c': {2, 3}} embedded_bqm = dimod.embed_bqm(bqm, embedding, nx.cycle_graph(4), chain_strength=1) # check that the energy has been preserved for config in itertools.product((0, 1), repeat=3): sample = dict(zip(('a', 'b', 'c'), config)) target_sample = { u: sample[v] for v, chain in embedding.items() for u in chain } # no chains broken self.assertAlmostEqual(bqm.energy(sample), embedded_bqm.energy(target_sample))
def test_embed_bqm_empty(self): bqm = dimod.BinaryQuadraticModel.empty(dimod.SPIN) embedded_bqm = dimod.embed_bqm(bqm, {}, {}) self.assertIsInstance(embedded_bqm, dimod.BinaryQuadraticModel) self.assertFalse(embedded_bqm) # should be empty
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_embed_bqm_identity(self): bqm = dimod.BinaryQuadraticModel({'a': -1}, {(0, 1): .5, (1, 'a'): -1.}, 1.0, dimod.BINARY) embedding = {v: {v} for v in bqm.linear} # identity embedding target_adj = bqm.to_networkx_graph() # identity target graph embedded_bqm = dimod.embed_bqm(bqm, embedding, target_adj) self.assertEqual(bqm, embedded_bqm)
def test_embedding_with_extra_chains(self): embedding = {0: [0, 1], 1: [2], 2: [3]} G = nx.cycle_graph(4) bqm = dimod.BinaryQuadraticModel.from_qubo({(0, 0): 1}) target_bqm = dimod.embed_bqm(bqm, embedding, G) for v in itertools.chain(*embedding.values()): self.assertIn(v, target_bqm)
def test_embed_bqm_subclass_propagation(self): class MyBQM(dimod.BinaryQuadraticModel): pass bqm = MyBQM.empty(dimod.BINARY) embedded_bqm = dimod.embed_bqm(bqm, {}, {}) self.assertIsInstance(embedded_bqm, dimod.BinaryQuadraticModel) self.assertIsInstance(embedded_bqm, MyBQM) self.assertFalse(embedded_bqm) # should be empty
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_embed_bqm_NAE3SAT_to_square(self): h = {'a': 0, 'b': 0, 'c': 0} J = {('a', 'b'): 1, ('b', 'c'): 1, ('a', 'c'): 1} bqm = dimod.BinaryQuadraticModel.from_ising(h, J) embedding = {'a': {0}, 'b': {1}, 'c': {2, 3}} embedded_bqm = dimod.embed_bqm(bqm, embedding, nx.cycle_graph(4), chain_strength=1) self.assertEqual( embedded_bqm, dimod.BinaryQuadraticModel( { 0: 0, 1: 0, 2: 0, 3: 0 }, { (0, 1): 1, (1, 2): 1, (2, 3): -1, (0, 3): 1 }, 1.0, # offset the energy from satisfying chains dimod.SPIN)) # check that the energy has been preserved for config in itertools.product((-1, 1), repeat=3): sample = dict(zip(('a', 'b', 'c'), config)) target_sample = { u: sample[v] for v, chain in embedding.items() for u in chain } # no chains broken self.assertAlmostEqual(bqm.energy(sample), embedded_bqm.energy(target_sample))
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, 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, 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, **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, **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)
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)
_, target_edgelist, target_adjacency = sampler.structure # Mapping between the graph of our problem—the multiplication circuit's graph with nodes labeled "a0", "b0" etc.—to the D-Wave QPU's numerically indexed qubits, is known as *minor-embedding*. A problem can be minor embedded onto the QPU in a variety of ways and this affects solution quality and performance. Ocean software provides tools suited for different types of problems; for example, [dwave-system](https://docs.ocean.dwavesys.com/projects/system/en/latest/) *EmbeddingComposite()* has a heuristic for automatic embedding. # This example uses a pre-calculated minor-embedding (see [below](#Further-Information) for details). # In[ ]: import dimod from helpers.embedding import embeddings # Set a pre-calculated minor-embeding embedding = embeddings[sampler.solver.id] bqm_embedded = dimod.embed_bqm(bqm, embedding, target_adjacency, 3.0) # Confirm mapping of variables from a0, b0, etc to indexed qubits print("Variable a0 in embedded BQM: ", 'a0' in bqm_embedded) # False print("First five nodes in QPU graph: ", sampler.structure.nodelist[:5]) # [0, 1, 2, 3, 4] # When the D‑Wave quantum computer solves a problem, it uses quantum phenomena such as superposition and tunneling to explore all possible solutions simultaneously and find a set of the best ones. Because the sampled solution is probabilistic, returned solutions may differ between runs. Typically, when submitting a problem to the system, we ask for many samples, not just one. This way, we see multiple “best” answers and reduce the probability of settling on a suboptimal answer. # In the code below, *num_reads* should provide enough samples to make it likely a valid answer is among them. # In[ ]: # Return num_reads solutions (responses are in the D-Wave's graph of indexed qubits) kwargs = {}
def test_embed_bqm_only_offset(self): bqm = dimod.BinaryQuadraticModel({}, {}, 1.0, dimod.SPIN) embedded_bqm = dimod.embed_bqm(bqm, {}, {}) self.assertEqual(bqm, embedded_bqm)