<commit_before>"""
Classes that deal with stretching, i.e. mapping a range of [0:1] values onto
another set of [0:1] values with a transformation
"""

import abc

import numpy as np

from astropy.extern import six

__all__ = ["LinearStretch", "SqrtStretch", "PowerStretch"]


@six.add_metaclass(abc.ABCMeta)
class BaseStretch(object):
    pass


class LinearStretch(BaseStretch):
    """
    A linear stretch: y = x
    """

    def __call__(self, values):
        return values

    def inverted(self):
        return LinearStretch()


class SqrtStretch(BaseStretch):
    """
    A square root stretch: y = sqrt(x)
    """

    def __call__(self, values):
        return np.sqrt(values)

    def inverted(self):
        return PowerStretch(2)


class PowerStretch(BaseStretch):
    """
    A power-law stretch: y = x ** a
    """

    def __init__(self, a):
        self.power = a

    def __call__(self, values):
        return values ** self.power

    def inverted(self):
        return PowerStretch(1. / self.power)<commit_msg>Added CompositeStretch and ContrastBias stretch<commit_after>"""
Classes that deal with stretching, i.e. mapping a range of [0:1] values onto
another set of [0:1] values with a transformation
"""

import abc

import numpy as np

from astropy.extern import six

__all__ = ["LinearStretch", "SqrtStretch", "PowerStretch"]


@six.add_metaclass(abc.ABCMeta)
class BaseStretch(object):

    def __add__(self, other):
        return CompositeStretch(other, self)


class CompositeStretch(BaseStretch):
    """
    A combiantion of two stretches.

    Parameters
    ----------
    stretch_1:
        The first stretch to apply.
    stretch_2:
        The second stretch to apply.
    """

    def __init__(self, stretch_1, stretch_2):
        super(CompositeStretch, self).__init__()
        self.stretch_1 = stretch_1
        self.stretch_2 = stretch_2

    def __call__(self, values):
        return self.stretch_2(self.stretch_1(values))

    def inverted(self):
        return CompositeStretch(self.stretch_2.inverted(),
                                self.stretch_1.inverted())


class LinearStretch(BaseStretch):
    """
    A linear stretch: y = x
    """

    def __call__(self, values):
        return values

    def inverted(self):
        return LinearStretch()


class SqrtStretch(BaseStretch):
    """
    A square root stretch: y = sqrt(x)
    """

    def __call__(self, values):
        return np.sqrt(values)

    def inverted(self):
        return PowerStretch(2)


class PowerStretch(BaseStretch):
    """
    A power-law stretch: y = x ** a
    """

    def __init__(self, a):
        super(PowerStretch, self).__init__()
        self.power = a

    def __call__(self, values):
        return values ** self.power

    def inverted(self):
        return PowerStretch(1. / self.power)


class ContrastBiasStretch(BaseStretch):
    """
    A stretch that takes into account contrast and bias: y = clip((x - bias) * contrast + 0.5, 0, 1)
    """

    def __init__(self, contrast, bias):
        super(ContrastBiasStretch, self).__init__()
        self.contrast = contrast
        self.bias = bias

    def __call__(self, values):
        return np.clip((values - self.bias) * self.contrast + 0.5, 0., 1.)

    def inverted(self):
        return InvertedContrastBiasStretch(self.contrast, self.bias)


class InvertedContrastBiasStretch(BaseStretch):
    """
    A stretch that takes into account contrast and bias: y = clip((x - bias) * contrast + 0.5, 0, 1)
    """

    def __init__(self, contrast, bias):
        super(InvertedContrastBiasStretch, self).__init__()
        self.contrast = contrast
        self.bias = bias

    def __call__(self, values):
        return np.clip((values - 0.5) / self.contrast + self.bias, 0., 1.)

    def inverted(self):
        return ContrastBiasStretch(self.contrast, self.bias)
{'fraction_non_alphanumeric': 0.11338338079213046, 'fraction_numerical': 0.010354646647683147, 'mean_word_length': 2.722543352601156, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5190525', 'n_tokens_mistral': 1315, 'n_tokens_neox': 1188, 'n_words': 330}