def test_energy_minimization(self):
        sample0 = {0: -1, 1: -1, 2: +1, 3: +1}
        sample1 = {0: +1, 1: -1, 2: +1, 3: -1}
        samples = [sample0, sample1]

        embedding = {'a': {0, 1}, 'b': {2}, 'c': {3}}

        linear = {'a': -1, 'b': 0, 'c': 0}
        quadratic = {}

        chain_break_method = eutil.MinimizeEnergy(linear=linear,
                                                  quadratic=quadratic)
        source_samples = eutil.unembed_samples(
            samples, embedding, chain_break_method=chain_break_method)

        source0, source1 = source_samples

        # no broken chains
        self.assertEqual(source0, {'a': -1, 'b': +1, 'c': +1})

        # in this case 'a' being spin-up minimizes the energy
        self.assertEqual(source1, {'a': +1, 'b': +1, 'c': -1})

        linear = {'a': 1, 'b': 0, 'c': 0}
        quadratic = {('a', 'b'): -5}

        chain_break_method = eutil.MinimizeEnergy(linear=linear,
                                                  quadratic=quadratic)
        source_samples = eutil.unembed_samples(
            samples, embedding, chain_break_method=chain_break_method)

        source0, source1 = source_samples

        # no broken chains
        self.assertEqual(source0, {'a': -1, 'b': +1, 'c': +1})

        # in this case 'a' being spin-up minimizes the energy due to the quadratic bias
        self.assertEqual(source1, {'a': +1, 'b': +1, 'c': -1})

        # now we need two broken chains
        sample = {0: +1, 1: -1, 2: +1, 3: -1, 4: +1}
        samples = [sample]

        embedding = {'a': {0, 1}, 'b': {2, 3}, 'c': {4}}

        quadratic = {('a', 'b'): -1, ('b', 'c'): 1}

        chain_break_method = eutil.MinimizeEnergy(quadratic=quadratic)
        source_samples = eutil.unembed_samples(
            samples, embedding, chain_break_method=chain_break_method)

        source, = source_samples

        self.assertEqual(source, {'b': -1, 'c': +1, 'a': -1})
示例#2
0
    def sample_ising(self, h, J, **parameters):
        """Sample from the provided unstructured Ising model.

        Args:
            h (list/dict): Linear terms of the model.
            J (dict of (int, int):float): Quadratic terms of the model.
            **parameters: Parameters for the sampling method, specified by the child sampler.

        Returns:
            :class:`dimod.Response`

        """
        if isinstance(h, list):
            h = dict(enumerate(h))

        # 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

        # get the embedding
        embedding = minorminer.find_embedding(J, target_edgelist)

        if J and not embedding:
            raise ValueError("no embedding found")

        # this should change in later versions
        if isinstance(embedding, list):
            embedding = dict(enumerate(embedding))

        h_emb, J_emb, J_chain = embutil.embed_ising(h, J, embedding,
                                                    target_adjacency)
        J_emb.update(J_chain)

        response = child.sample_ising(h_emb, J_emb, **parameters)

        # unembed the problem and save to a new response object
        samples = embutil.unembed_samples(
            response,
            embedding,
            chain_break_method=embutil.minimize_energy,
            linear=h,
            quadratic=J)  # needed by minimize_energy

        # source_response = dimod.Response(dimod.SPIN)
        data_vectors = response.data_vectors
        data_vectors['energy'] = [
            dimod.ising_energy(sample, h, J) for sample in samples
        ]

        return dimod.Response.from_dicts(samples,
                                         data_vectors,
                                         info=response.info,
                                         vartype=dimod.SPIN)
示例#3
0
    def sample_ising(self, h, J, **kwargs):
        """Sample from the sub Chimera lattice.

        Args:
            h (list/dict): Linear terms of the model.
            J (dict of (int, int):float): Quadratic terms of the model.
            **kwargs: Parameters for the sampling method, specified per solver.

        Returns:
            :class:`dimod.SpinResponse`

        """
        __, __, adjacency = self.structure
        if not all(v in adjacency for v in h):
            raise ValueError(
                "nodes in linear bias do not map to the structure")
        if not all(u in adjacency[v] for u, v in J):
            raise ValueError(
                "edges in quadratic bias do not map to the structure")

        # apply the embeddings to the given problem to tile it across the child sampler
        h_embs = {}
        J_embs = {}
        for embedding in self.embeddings:
            __, __, target_adjacency = self.child.structure
            h_emb, J_emb, J_chain = embutil.embed_ising(
                h, J, embedding, target_adjacency)
            assert (not J_chain)
            h_embs.update(h_emb)
            J_embs.update(J_emb)

        # solve the problem on the child system
        response = self.child.sample_ising(h_embs, J_embs, **kwargs)

        # unembed the tiled problem and combine results into one response object
        source_response = dimod.Response(dimod.SPIN)
        for embedding in self.embeddings:
            samples = embutil.unembed_samples(
                response,
                embedding,
                chain_break_method=embutil.minimize_energy,
                linear=h,
                quadratic=J)  # needed by minimize_energy
            for sample, (__, data) in zip(samples,
                                          response.df_data.iterrows()):
                data['energy'] = dimod.ising_energy(sample, h, J)
                source_response.add_sample(sample, **data.to_dict())

        return source_response
示例#4
0
    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}}

        # specify that majority vote should be used
        source_samples = eutil.unembed_samples(
            samples, embedding, chain_break_method=eutil.discard)

        # 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}}

        # specify that majority vote should be used
        source_samples = eutil.unembed_samples(
            samples, embedding, chain_break_method=eutil.discard)

        # only the first sample should be returned
        self.assertEqual(len(source_samples), 1)
        self.assertEqual(source_samples, [{'a': -1, 'b': +1}])
示例#5
0
    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}}

        # specify that majority vote should be used
        source_samples = eutil.unembed_samples(
            samples, embedding, chain_break_method=eutil.majority_vote)

        source0, source1 = source_samples

        self.assertEqual(source0['a'], -1)
        self.assertEqual(source1['a'], +1)
示例#6
0
    def test_discard_with_dimod(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}, 'b': {2}}

        # load the samples into a dimod response
        response = dimod.SpinResponse()
        response.add_samples_from(samples, (0 for __ in samples))

        # specify that majority vote should be used
        source_samples = eutil.unembed_samples(
            response, embedding, chain_break_method=eutil.discard)

        # only the first sample should be returned
        self.assertEqual(len(source_samples), 1)
        self.assertEqual(source_samples, [{'a': -1, 'b': +1}])
示例#7
0
    def test_majority_vote_with_dimod(self):
        sample0 = {0: -1, 1: -1, 2: +1}
        sample1 = {0: +1, 1: -1, 2: +1}
        samples = [sample0, sample1]

        embedding = {'a': {0, 1, 2}}

        # load the samples into a dimod response
        response = dimod.SpinResponse()
        response.add_samples_from(samples, (0 for __ in samples))

        # specify that majority vote should be used
        source_samples = eutil.unembed_samples(
            response, embedding, chain_break_method=eutil.majority_vote)

        source0, source1 = source_samples

        self.assertEqual(source0['a'], -1)
        self.assertEqual(source1['a'], +1)
示例#8
0
    def test_typical(self):
        """simple smoke tests trying to replicate 'normal' usage."""

        nodes = range(10)
        target_samples = [{v: random.choice((-1, 1))
                           for v in nodes} for __ in range(100)]

        # embedding is map half the target vars to one source, and the other half to
        # another
        embedding = {'a': range(5), 'b': range(5, 10)}

        source_samples = eutil.unembed_samples(target_samples, embedding)

        # not checking correctness of samples, just that they have the correct form
        self.assertEqual(len(source_samples), 100)
        for sample in source_samples:
            self.assertIsInstance(sample, dict)
            self.assertEqual(set(sample), {'a', 'b'})  # maps to source vars
            self.assertTrue(all(bias in (-1, 1) for bias in sample.values()))
示例#9
0
    def test_typical_dimod_response(self):
        """unembed should be compatible with the dimod response object"""
        nodes = range(10)
        target_samples = [{v: random.choice((-1, 1))
                           for v in nodes} for __ in range(100)]

        # load the samples into a dimod response
        response = dimod.SpinResponse()
        response.add_samples_from(target_samples, (0 for __ in target_samples))

        # embedding is map half the target vars to one source, and the other half to
        # another
        embedding = {'a': range(5), 'b': range(5, 10)}

        # use the response as the target_samples
        source_samples = eutil.unembed_samples(response, embedding)

        # not checking correctness of samples, just that they have the correct form
        self.assertEqual(len(source_samples), 100)
        for sample in source_samples:
            self.assertIsInstance(sample, dict)
            self.assertEqual(set(sample), {'a', 'b'})  # maps to source vars
            self.assertTrue(all(bias in (-1, 1) for bias in sample.values()))
示例#10
0
    def test_energy_minimization(self):
        sample0 = {0: -1, 1: -1, 2: +1, 3: +1}
        sample1 = {0: +1, 1: -1, 2: +1, 3: -1}
        samples = [sample0, sample1]

        embedding = {'a': {0, 1}, 'b': {2}, 'c': {3}}

        # minimize energy requires `linear` and `quadratic` keyword args
        with self.assertRaises(TypeError):
            eutil.unembed_samples(samples,
                                  embedding,
                                  chain_break_method=eutil.minimize_energy)

        linear = {'a': -1, 'b': 0, 'c': 0}
        quadratic = {}

        source_samples = eutil.unembed_samples(
            samples,
            embedding,
            chain_break_method=eutil.minimize_energy,
            linear=linear,
            quadratic=quadratic)

        source0, source1 = source_samples

        # no broken chains
        self.assertEqual(source0, {'a': -1, 'b': +1, 'c': +1})

        # in this case 'a' being spin-up minimizes the energy
        self.assertEqual(source1, {'a': +1, 'b': +1, 'c': -1})

        linear = {'a': 1, 'b': 0, 'c': 0}
        quadratic = {('a', 'b'): -5}

        source_samples = eutil.unembed_samples(
            samples,
            embedding,
            chain_break_method=eutil.minimize_energy,
            linear=linear,
            quadratic=quadratic)

        source0, source1 = source_samples

        # no broken chains
        self.assertEqual(source0, {'a': -1, 'b': +1, 'c': +1})

        # in this case 'a' being spin-up minimizes the energy due to the quadratic bias
        self.assertEqual(source1, {'a': +1, 'b': +1, 'c': -1})

        # now we need two broken chains
        sample = {0: +1, 1: -1, 2: +1, 3: -1, 4: +1}
        samples = [sample]

        embedding = {'a': {0, 1}, 'b': {2, 3}, 'c': {4}}

        quadratic = {('a', 'b'): -1, ('b', 'c'): 1}

        source_samples = eutil.unembed_samples(
            samples,
            embedding,
            chain_break_method=eutil.minimize_energy,
            quadratic=quadratic)

        source, = source_samples

        self.assertEqual(source, {'b': -1, 'c': +1, 'a': -1})
示例#11
0
    def sample_ising(self, h, J, **kwargs):
        """Sample from the sub-Chimera lattice.

        Args:
            h (list/dict): Linear terms of the model.
            J (dict of (int, int):float): Quadratic terms of the model.
            **kwargs: Parameters for the sampling method, specified per solver.

        Returns:
            :class:`dimod.Response`

        """
        __, __, adjacency = self.structure
        if not all(v in adjacency for v in h):
            raise ValueError(
                "nodes in linear bias do not map to the structure")
        if not all(u in adjacency[v] for u, v in J):
            raise ValueError(
                "edges in quadratic bias do not map to the structure")

        # apply the embeddings to the given problem to tile it across the child sampler
        h_embs = {}
        J_embs = {}
        for embedding in self.embeddings:
            __, __, target_adjacency = self.child.structure
            h_emb, J_emb, J_chain = embutil.embed_ising(
                h, J, embedding, target_adjacency)
            assert (not J_chain)
            h_embs.update(h_emb)
            J_embs.update(J_emb)

        # solve the problem on the child system
        response = self.child.sample_ising(h_embs, J_embs, **kwargs)

        data_vectors = response.data_vectors.copy()

        source_response = None

        for embedding in self.embeddings:
            samples = embutil.unembed_samples(
                response,
                embedding,
                chain_break_method=embutil.minimize_energy,
                linear=h,
                quadratic=J)  # needed by minimize_energy

            # override the energy because it might have changed
            data_vectors['energy'] = [
                dimod.ising_energy(sample, h, J) for sample in samples
            ]

            tile_response = dimod.Response.from_dicts(samples, data_vectors)

            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
示例#12
0
    def sample_ising(self, h, J, apply_flux_bias_offsets=True, **kwargs):
        """Sample from the given Ising model.

        Args:

            h (list/dict): Linear terms of the model.

            J (dict of (int, int):float): Quadratic terms of the model.

            apply_flux_bias_offsets (bool, optional):
                If True, use the calculated flux_bias offsets (if available).

            **kwargs: Parameters for the sampling method, specified by the child sampler.

        """

        __, __, adjacency = self.structure
        if not all(v in adjacency for v in h):
            raise ValueError(
                "nodes in linear bias do not map to the structure")
        if not all(u in adjacency[v] for u, v in J):
            raise ValueError(
                "edges in linear bias do not map to the structure")

        # apply the embedding to the given problem to map it to the child sampler
        __, __, target_adjacency = self.child.structure
        h_emb, J_emb, J_chain = embutil.embed_ising(h, J, self.embedding,
                                                    target_adjacency,
                                                    self.chain_strength)
        J_emb.update(J_chain)

        # 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_ising(h_emb, J_emb, **kwargs)

        # unembed the problem and save to a new response object
        samples = embutil.unembed_samples(
            response.samples(sorted_by=None),
            self.embedding,
            chain_break_method=embutil.minimize_energy,
            linear=h,
            quadratic=J)  # needed by minimize_energy

        # source_response = dimod.Response(dimod.SPIN)
        data_vectors = response.data_vectors
        data_vectors['energy'] = [
            dimod.ising_energy(sample, h, J) for sample in samples
        ]

        return dimod.Response.from_dicts(samples,
                                         data_vectors,
                                         info=response.info,
                                         vartype=dimod.SPIN)