Exemplo n.º 1
0
def poly_energies(samples_like, poly):
    """Calculates energy of samples from a higher order polynomial.

    Args:
        sample (samples_like):
            A collection of raw samples. `samples_like` is an extension of
            NumPy's array_like structure. See :func:`.as_samples`.

        poly (dict):
            Polynomial as a dict of form {term: bias, ...}, where `term` is a 
            tuple of variables and `bias` the associated bias. Variable
            labeling/indexing of terms in poly dict must match that of the
            sample(s).

    Returns:
        list/:obj:`numpy.ndarray`: The energy of the sample(s).

    """
    sample, labels = as_samples(samples_like)
    idx, label = zip(*enumerate(labels))
    labeldict = dict(zip(label, idx))

    num_samples = len(sample)
    return sum(_prod_d([sample[:, labeldict[v]] for v in variables],
                       num_samples) * bias for variables, bias in poly.items())
Exemplo n.º 2
0
    def energies(self, samples_like, dtype=np.float):
        """The energies of the given samples.

        Args:
            samples_like (samples_like):
                A collection of raw samples. `samples_like` is an extension of
                NumPy's array_like structure. See :func:`.as_samples`.

            dtype (:class:`numpy.dtype`, optional):
                The data type of the returned energies. Defaults to float.

        Returns:
            :obj:`numpy.ndarray`: The energies.

        """
        samples, labels = as_samples(samples_like)
        if labels:
            idx, label = zip(*enumerate(labels))
            labeldict = dict(zip(label, idx))
        else:
            labeldict = {}

        num_samples = samples.shape[0]

        energies = np.zeros(num_samples, dtype=dtype)
        for term, bias in self.items():
            if len(term) == 0:
                energies += bias
            else:
                energies += np.prod([samples[:, labeldict[v]] for v in term],
                                    axis=0) * bias

        return energies
Exemplo n.º 3
0
def poly_energy(sample_like, poly):
    """Calculates energy of a sample from a higher order polynomial.

    Args:
         sample (samples_like):
            A raw sample. `samples_like` is an extension of NumPy's
            array_like structure. See :func:`.as_samples`.

        poly (dict):
            Polynomial as a dict of form {term: bias, ...}, where `term` is a
            tuple of variables and `bias` the associated bias.

    Returns:
        float: The energy of the sample.

    """
    sample, labels = as_samples(sample_like)
    idx, label = zip(*enumerate(labels))
    labeldict = dict(zip(label, idx))
    num_samples = len(sample)

    if num_samples > 1:
        raise ValueError('poly_energy accepts a single sample. For multiple '
                         'samples use poly_energies')
    else:
        return sum(_prod(sample[0][labeldict[v]] for v in variables) * bias
                   for variables, bias in poly.items())
Exemplo n.º 4
0
    def energies(self, samples_like, dtype: DTypeLike = None):
        samples, labels = as_samples(samples_like)

        if len(labels) != self.num_variables():
            raise ValueError("variable_order does not match the number of "
                             "variables")

        ldata = np.asarray([self.get_linear(v) for v in labels])

        label_to_idx = {v: idx for idx, v in enumerate(labels)}
        irow = []
        icol = []
        qdata = []
        for u, v, bias in self.iter_quadratic():
            irow.append(label_to_idx[u])
            icol.append(label_to_idx[v])
            qdata.append(bias)

        irow = np.asarray(irow, dtype=int)  # type: ignore[assignment]
        icol = np.asarray(icol, dtype=int)  # type: ignore[assignment]
        qdata = np.asarray(qdata)  # type: ignore[assignment]

        energies = samples.dot(ldata)
        energies += (samples[:, irow] * samples[:, icol]).dot(qdata)
        energies += ldata.dtype.type(self.offset)

        return np.asarray(energies, dtype=dtype)
Exemplo n.º 5
0
    def energies(self, samples_like, dtype: DTypeLike = None):
        samples, labels = as_samples(samples_like, copy=True)

        if self._vartype is BINARY:  # binary -> spin
            samples *= 2
            samples -= 1
        else:  # spin -> binary
            samples += 1
            samples //= 2

        return self.data.energies((samples, labels), dtype=dtype)
Exemplo n.º 6
0
    def energies(self, samples):
        samples, labels = as_samples(samples, dtype=self._cydqm.case_dtype)

        # reorder as needed
        if len(labels) != self.num_variables():
            raise ValueError(
                "Given sample(s) have incorrect number of variables")
        if self.variables != labels:
            # need to reorder the samples
            label_to_idx = dict((v, i) for i, v in enumerate(labels))

            try:
                order = [label_to_idx[v] for v in self.variables]
            except KeyError:
                raise ValueError("given samples-like does not match labels")

            samples = samples[:, order]

        return np.asarray(self._cydqm.energies(samples))
Exemplo n.º 7
0
    def energies(self, samples_like, dtype=None):
        """Determine the energies of the given samples.

        Args:
            samples_like (samples_like):
                A collection of raw samples. `samples_like` is an extension of
                NumPy's array_like structure. See :func:`.as_samples`.

            dtype (:class:`numpy.dtype`, optional):
                The data type of the returned energies.

        Returns:
            :obj:`numpy.ndarray`: The energies.

        """
        samples, labels = as_samples(samples_like)

        ldata, (irow, icol, qdata), offset \
            = self.to_numpy_vectors(variable_order=labels, dtype=dtype)

        energies = samples.dot(ldata) + (samples[:, irow]*samples[:, icol]).dot(qdata) + offset
        return np.asarray(energies, dtype=dtype)  # handle any type promotions
Exemplo n.º 8
0
    def sample_dqm(self, dqm, **kwargs):
        """Sample from a discrete quadratic model.

        Args:
            dqm (:obj:`~dimod.DiscreteQuadraticModel`):
                Discrete quadratic model to be sampled from.

        Returns:
            :obj:`~dimod.SampleSet`

        """
        Sampler.remove_unknown_kwargs(self, **kwargs)

        n = dqm.num_variables()
        if n == 0:
            return SampleSet.from_samples([], 'DISCRETE', energy=[])

        possible_samples = as_samples(
            (_all_cases_dqm(dqm), list(dqm.variables)))
        energies = dqm.energies(possible_samples)

        response = SampleSet.from_samples(possible_samples, 'DISCRETE',
                                          energies)
        return response
Exemplo n.º 9
0
    def parse_initial_states(self,
                             bqm,
                             initial_states=None,
                             initial_states_generator='random',
                             num_reads=None,
                             seed=None):
        """Parses/generates initial states for an initialized sampler.

        Args:
            bqm (:class:`~dimod.BinaryQuadraticModel`):
                The binary quadratic model.

            num_reads (int, optional, default=len(initial_states) or 1):
                Number of reads. If `num_reads` is not explicitly given, it is
                selected to match the number of initial states given.
                If no initial states are given, it defaults to 1.

            initial_states (samples-like, optional, default=None):
                One or more samples, each defining an initial state for all the
                problem variables. Initial states are given one per read, but
                if fewer than `num_reads` initial states are defined,
                additional values are generated as specified by
                `initial_states_generator`. See func:`.as_samples` for a
                description of "samples-like".

            initial_states_generator ({'none', 'tile', 'random'}, optional, default='random'):
                Defines the expansion of `initial_states` if fewer than
                `num_reads` are specified:

                * "none":
                    If the number of initial states specified is smaller than
                    `num_reads`, raises ValueError.

                * "tile":
                    Reuses the specified initial states if fewer than
                    `num_reads` or truncates if greater.

                * "random":
                    Expands the specified initial states with randomly
                    generated states if fewer than `num_reads` or truncates if
                    greater.

            seed (int (32-bit unsigned integer), optional):
                Seed to use for the PRNG. Specifying a particular seed with a
                constant set of parameters produces identical results. If not
                provided, a random seed is chosen.

        Returns:
            A named tuple with `['initial_states', 'initial_states_generator',
            'num_reads', 'seed']` as generated by this function.

        """

        num_variables = len(bqm)

        # validate/initialize initial_states
        if initial_states is None:
            initial_states_array = np.empty((0, num_variables), dtype=np.int8)
            initial_states_variables = list(bqm.variables)
            initial_states_vartype = bqm.vartype
        else:
            initial_states_array, initial_states_variables = \
                as_samples(initial_states)

            # confirm that the vartype matches and/or make it match
            if isinstance(initial_states, SampleSet):
                initial_states_vartype = initial_states.vartype
            else:
                # check based on values, defaulting to match the current bqm
                initial_states_vartype = infer_vartype(
                    initial_states_array) or bqm.vartype

            # confirm that the variables match
            if bqm.variables ^ initial_states_variables:
                raise ValueError("mismatch between variables in "
                                 "'initial_states' and 'bqm'")

        # match the vartype of the initial_states to the bqm
        if initial_states_vartype is Vartype.SPIN and bqm.vartype is Vartype.BINARY:
            initial_states_array += 1
            initial_states_array //= 2
        elif initial_states_vartype is Vartype.BINARY and bqm.vartype is Vartype.SPIN:
            initial_states_array *= 2
            initial_states_array -= 1

        # validate num_reads and/or infer them from initial_states
        if num_reads is None:
            num_reads = len(initial_states_array) or 1
        if not isinstance(num_reads, Integral):
            raise TypeError("'num_reads' should be a positive integer")
        if num_reads < 1:
            raise ValueError("'num_reads' should be a positive integer")

        # fill/generate the initial states as needed
        if initial_states_generator not in self._generators:
            raise ValueError("unknown value for 'initial_states_generator'")

        extrapolate = self._generators[initial_states_generator]
        initial_states_array = extrapolate(initial_states=initial_states_array,
                                           num_reads=num_reads,
                                           num_variables=num_variables,
                                           seed=seed,
                                           vartype=bqm.vartype)
        initial_states_array = self._truncate_filter(initial_states_array,
                                                     num_reads)

        sampleset = SampleSet.from_samples_bqm(
            (initial_states_array, initial_states_variables), bqm)

        return ParsedInputs(sampleset, initial_states_generator, num_reads,
                            seed)