def sample_poly(self, poly, scalar=None, bias_range=1, poly_range=None,
                    ignored_terms=None, **parameters):
        """Scale and sample from the given binary polynomial.

        If scalar is not given, problem is scaled based on bias and polynomial
        ranges. See :meth:`.BinaryPolynomial.scale` and
        :meth:`.BinaryPolynomial.normalize`

        Args:
            poly (obj:`.BinaryPolynomial`): A binary polynomial.

            scalar (number, optional):
                Value by which to scale the energy range of the binary polynomial.

            bias_range (number/pair, optional, default=1):
                Value/range by which to normalize the all the biases, or if
                `poly_range` is provided, just the linear biases.

            poly_range (number/pair, optional):
                Value/range by which to normalize the higher order biases.

            ignored_terms (iterable, optional):
                Biases associated with these terms are not scaled.

            **parameters:
                Other parameters for the sampling method, specified by
                the child sampler.

        """

        if ignored_terms is None:
            ignored_terms = set()
        else:
            ignored_terms = {frozenset(term) for term in ignored_terms}

        # scale and normalize happen in-place so we need to make a copy
        original, poly = poly, poly.copy()

        if scalar is not None:
            poly.scale(scalar, ignored_terms=ignored_terms)
        else:
            poly.normalize(bias_range=bias_range, poly_range=poly_range,
                           ignored_terms=ignored_terms)

            # we need to know how much we scaled by, which we can do by looking
            # at the biases
            try:
                v = next(v for v, bias in original.items()
                         if bias and v not in ignored_terms)
            except StopIteration:
                # nothing to scale
                scalar = 1
            else:
                scalar = poly[v] / original[v]

        sampleset = self.child.sample_poly(poly, **parameters)

        if ignored_terms:
            # we need to recalculate the energy
            sampleset.record.energy = original.energies((sampleset.record.sample,
                                                         sampleset.variables))
        else:
            sampleset.record.energy /= scalar

        return sampleset
Scale and sample from the given binary polynomial.

        If scalar is not given, problem is scaled based on bias and polynomial
        ranges. See :meth:`.BinaryPolynomial.scale` and
        :meth:`.BinaryPolynomial.normalize`

        Args:
            poly (obj:`.BinaryPolynomial`): A binary polynomial.

            scalar (number, optional):
                Value by which to scale the energy range of the binary polynomial.

            bias_range (number/pair, optional, default=1):
                Value/range by which to normalize the all the biases, or if
                `poly_range` is provided, just the linear biases.

            poly_range (number/pair, optional):
                Value/range by which to normalize the higher order biases.

            ignored_terms (iterable, optional):
                Biases associated with these terms are not scaled.

            **parameters:
                Other parameters for the sampling method, specified by
                the child sampler.