def polymorph_response(response, poly, bqm,
                       penalty_strength=None,
                       keep_penalty_variables=True,
                       discard_unsatisfied=False):
    """ Transforms the sampleset for the higher order problem.

    Given a response of a penalized HUBO, this function creates a new sampleset
    object, taking into account penalty information and calculates the
    energies of samples for the higherorder problem.

    Args:
        response (:obj:`.SampleSet`): response for a penalized hubo.

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

        bqm (:obj:`dimod.BinaryQuadraticModel`): Binary quadratic model of the
            reduced problem.

        penalty_strength (float, optional): default is None, if provided,
            will be added to the info field of the returned sampleSet object.

        keep_penalty_variables (bool, optional): default is True. if False
            will remove the variables used for penalty from the samples

        discard_unsatisfied (bool, optional): default is False. If True
            will discard samples that do not satisfy the penalty conditions.

    Returns:
        (:obj:`.SampleSet'): A sampleSet object that has additional penalty
            information. The energies of samples are calculated for the HUBO
            ignoring the penalty variables.

    """
    record = response.record
    penalty_vector = penalty_satisfaction(response, bqm)
    original_variables = bqm.variables

    if discard_unsatisfied:
        samples_to_keep = list(map(bool, list(penalty_vector)))
        penalty_vector = np.array([True] * np.sum(samples_to_keep))
    else:
        samples_to_keep = list(map(bool, [1] * len(record.sample)))

    samples = record.sample[samples_to_keep]
    energy_vector = poly.energies((samples, response.variables))

    if not keep_penalty_variables:
        original_variables = poly.variables
        idxs = [response.variables.index[v] for v in original_variables]
        samples = np.asarray(samples[:, idxs])

    num_samples, num_variables = np.shape(samples)

    datatypes = [('sample', np.dtype(np.int8), (num_variables,)),
                 ('energy', energy_vector.dtype),
                 ('penalty_satisfaction',
                  penalty_vector.dtype)]
    datatypes.extend((name, record[name].dtype, record[name].shape[1:])
                     for name in record.dtype.names if
                     name not in {'sample',
                                  'energy'})

    data = np.rec.array(np.empty(num_samples, dtype=datatypes))
    data.sample = samples
    data.energy = energy_vector
    for name in record.dtype.names:
        if name not in {'sample', 'energy'}:
            data[name] = record[name][samples_to_keep]

    data['penalty_satisfaction'] = penalty_vector
    response.info['reduction'] = bqm.info['reduction']
    if penalty_strength is not None:
        response.info['penalty_strength'] = penalty_strength
    return SampleSet(data, original_variables, response.info,
                     response.vartype)
Transforms the sampleset for the higher order problem.

    Given a response of a penalized HUBO, this function creates a new sampleset
    object, taking into account penalty information and calculates the
    energies of samples for the higherorder problem.

    Args:
        response (:obj:`.SampleSet`): response for a penalized hubo.

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

        bqm (:obj:`dimod.BinaryQuadraticModel`): Binary quadratic model of the
            reduced problem.

        penalty_strength (float, optional): default is None, if provided,
            will be added to the info field of the returned sampleSet object.

        keep_penalty_variables (bool, optional): default is True. if False
            will remove the variables used for penalty from the samples

        discard_unsatisfied (bool, optional): default is False. If True
            will discard samples that do not satisfy the penalty conditions.

    Returns:
        (:obj:`.SampleSet'): A sampleSet object that has additional penalty
            information. The energies of samples are calculated for the HUBO
            ignoring the penalty variables.